Statistics
| Branch: | Revision:

root / hw / ide.c @ c3d78997

History | View | Annotate | Download (79.7 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 98087450 bellard
static void cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf, 
947 98087450 bellard
                           int sector_size)
948 98087450 bellard
{
949 98087450 bellard
    switch(sector_size) {
950 98087450 bellard
    case 2048:
951 98087450 bellard
        bdrv_read(bs, (int64_t)lba << 2, buf, 4);
952 98087450 bellard
        break;
953 98087450 bellard
    case 2352:
954 8ccad811 bellard
        bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
955 8ccad811 bellard
        cd_data_to_raw(buf, lba);
956 98087450 bellard
        break;
957 98087450 bellard
    default:
958 98087450 bellard
        break;
959 98087450 bellard
    }
960 98087450 bellard
}
961 98087450 bellard
962 5391d806 bellard
/* The whole ATAPI transfer logic is handled in this function */
963 5391d806 bellard
static void ide_atapi_cmd_reply_end(IDEState *s)
964 5391d806 bellard
{
965 5391d806 bellard
    int byte_count_limit, size;
966 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
967 5391d806 bellard
    printf("reply: tx_size=%d elem_tx_size=%d index=%d\n", 
968 5391d806 bellard
           s->packet_transfer_size,
969 5391d806 bellard
           s->elementary_transfer_size,
970 5391d806 bellard
           s->io_buffer_index);
971 5391d806 bellard
#endif
972 5391d806 bellard
    if (s->packet_transfer_size <= 0) {
973 5391d806 bellard
        /* end of transfer */
974 5391d806 bellard
        ide_transfer_stop(s);
975 5391d806 bellard
        s->status = READY_STAT;
976 5391d806 bellard
        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
977 5391d806 bellard
        ide_set_irq(s);
978 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
979 5391d806 bellard
        printf("status=0x%x\n", s->status);
980 5391d806 bellard
#endif
981 5391d806 bellard
    } else {
982 5391d806 bellard
        /* see if a new sector must be read */
983 98087450 bellard
        if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
984 98087450 bellard
            cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
985 5391d806 bellard
            s->lba++;
986 5391d806 bellard
            s->io_buffer_index = 0;
987 5391d806 bellard
        }
988 5391d806 bellard
        if (s->elementary_transfer_size > 0) {
989 5391d806 bellard
            /* there are some data left to transmit in this elementary
990 5391d806 bellard
               transfer */
991 98087450 bellard
            size = s->cd_sector_size - s->io_buffer_index;
992 5391d806 bellard
            if (size > s->elementary_transfer_size)
993 5391d806 bellard
                size = s->elementary_transfer_size;
994 5391d806 bellard
            ide_transfer_start(s, s->io_buffer + s->io_buffer_index, 
995 5391d806 bellard
                               size, ide_atapi_cmd_reply_end);
996 5391d806 bellard
            s->packet_transfer_size -= size;
997 5391d806 bellard
            s->elementary_transfer_size -= size;
998 5391d806 bellard
            s->io_buffer_index += size;
999 5391d806 bellard
        } else {
1000 5391d806 bellard
            /* a new transfer is needed */
1001 5391d806 bellard
            s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
1002 5391d806 bellard
            byte_count_limit = s->lcyl | (s->hcyl << 8);
1003 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1004 5391d806 bellard
            printf("byte_count_limit=%d\n", byte_count_limit);
1005 5391d806 bellard
#endif
1006 5391d806 bellard
            if (byte_count_limit == 0xffff)
1007 5391d806 bellard
                byte_count_limit--;
1008 5391d806 bellard
            size = s->packet_transfer_size;
1009 5391d806 bellard
            if (size > byte_count_limit) {
1010 5391d806 bellard
                /* byte count limit must be even if this case */
1011 5391d806 bellard
                if (byte_count_limit & 1)
1012 5391d806 bellard
                    byte_count_limit--;
1013 5391d806 bellard
                size = byte_count_limit;
1014 5391d806 bellard
            }
1015 a136e5a8 bellard
            s->lcyl = size;
1016 a136e5a8 bellard
            s->hcyl = size >> 8;
1017 5391d806 bellard
            s->elementary_transfer_size = size;
1018 5391d806 bellard
            /* we cannot transmit more than one sector at a time */
1019 5391d806 bellard
            if (s->lba != -1) {
1020 98087450 bellard
                if (size > (s->cd_sector_size - s->io_buffer_index))
1021 98087450 bellard
                    size = (s->cd_sector_size - s->io_buffer_index);
1022 5391d806 bellard
            }
1023 5391d806 bellard
            ide_transfer_start(s, s->io_buffer + s->io_buffer_index, 
1024 5391d806 bellard
                               size, ide_atapi_cmd_reply_end);
1025 5391d806 bellard
            s->packet_transfer_size -= size;
1026 5391d806 bellard
            s->elementary_transfer_size -= size;
1027 5391d806 bellard
            s->io_buffer_index += size;
1028 5391d806 bellard
            ide_set_irq(s);
1029 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1030 5391d806 bellard
            printf("status=0x%x\n", s->status);
1031 5391d806 bellard
#endif
1032 5391d806 bellard
        }
1033 5391d806 bellard
    }
1034 5391d806 bellard
}
1035 5391d806 bellard
1036 5391d806 bellard
/* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
1037 5391d806 bellard
static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
1038 5391d806 bellard
{
1039 5391d806 bellard
    if (size > max_size)
1040 5391d806 bellard
        size = max_size;
1041 5391d806 bellard
    s->lba = -1; /* no sector read */
1042 5391d806 bellard
    s->packet_transfer_size = size;
1043 5391d806 bellard
    s->elementary_transfer_size = 0;
1044 5391d806 bellard
    s->io_buffer_index = 0;
1045 5391d806 bellard
1046 5391d806 bellard
    s->status = READY_STAT;
1047 5391d806 bellard
    ide_atapi_cmd_reply_end(s);
1048 5391d806 bellard
}
1049 5391d806 bellard
1050 5391d806 bellard
/* start a CD-CDROM read command */
1051 98087450 bellard
static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
1052 98087450 bellard
                                   int sector_size)
1053 5391d806 bellard
{
1054 5391d806 bellard
    s->lba = lba;
1055 98087450 bellard
    s->packet_transfer_size = nb_sectors * sector_size;
1056 5391d806 bellard
    s->elementary_transfer_size = 0;
1057 98087450 bellard
    s->io_buffer_index = sector_size;
1058 98087450 bellard
    s->cd_sector_size = sector_size;
1059 5391d806 bellard
1060 5391d806 bellard
    s->status = READY_STAT;
1061 5391d806 bellard
    ide_atapi_cmd_reply_end(s);
1062 5391d806 bellard
}
1063 5391d806 bellard
1064 98087450 bellard
/* ATAPI DMA support */
1065 8ccad811 bellard
1066 8ccad811 bellard
/* XXX: handle read errors */
1067 8ccad811 bellard
static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
1068 98087450 bellard
{
1069 8ccad811 bellard
    BMDMAState *bm = opaque;
1070 8ccad811 bellard
    IDEState *s = bm->ide_if;
1071 8ccad811 bellard
    int data_offset, n;
1072 8ccad811 bellard
1073 8ccad811 bellard
    if (s->io_buffer_size > 0) {
1074 8ccad811 bellard
        if (s->cd_sector_size == 2352) {
1075 8ccad811 bellard
            n = 1;
1076 8ccad811 bellard
            cd_data_to_raw(s->io_buffer, s->lba);
1077 8ccad811 bellard
        } else {
1078 8ccad811 bellard
            n = s->io_buffer_size >> 11;
1079 98087450 bellard
        }
1080 8ccad811 bellard
        s->packet_transfer_size -= s->io_buffer_size;
1081 8ccad811 bellard
        s->lba += n;
1082 8ccad811 bellard
        if (dma_buf_rw(bm, 1) == 0)
1083 8ccad811 bellard
            goto eot;
1084 98087450 bellard
    }
1085 8ccad811 bellard
1086 98087450 bellard
    if (s->packet_transfer_size <= 0) {
1087 98087450 bellard
        s->status = READY_STAT;
1088 98087450 bellard
        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1089 98087450 bellard
        ide_set_irq(s);
1090 8ccad811 bellard
    eot:
1091 8ccad811 bellard
        bm->status &= ~BM_STATUS_DMAING;
1092 8ccad811 bellard
        bm->status |= BM_STATUS_INT;
1093 8ccad811 bellard
        bm->dma_cb = NULL;
1094 8ccad811 bellard
        bm->ide_if = NULL;
1095 8ccad811 bellard
        bm->aiocb = NULL;
1096 8ccad811 bellard
        return;
1097 8ccad811 bellard
    }
1098 8ccad811 bellard
    
1099 8ccad811 bellard
    s->io_buffer_index = 0;
1100 8ccad811 bellard
    if (s->cd_sector_size == 2352) {
1101 8ccad811 bellard
        n = 1;
1102 8ccad811 bellard
        s->io_buffer_size = s->cd_sector_size;
1103 8ccad811 bellard
        data_offset = 16;
1104 8ccad811 bellard
    } else {
1105 8ccad811 bellard
        n = s->packet_transfer_size >> 11;
1106 8ccad811 bellard
        if (n > (MAX_MULT_SECTORS / 4))
1107 8ccad811 bellard
            n = (MAX_MULT_SECTORS / 4);
1108 8ccad811 bellard
        s->io_buffer_size = n * 2048;
1109 8ccad811 bellard
        data_offset = 0;
1110 98087450 bellard
    }
1111 8ccad811 bellard
#ifdef DEBUG_AIO
1112 8ccad811 bellard
    printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
1113 8ccad811 bellard
#endif
1114 8ccad811 bellard
    bm->aiocb = bdrv_aio_read(s->bs, (int64_t)s->lba << 2, 
1115 8ccad811 bellard
                              s->io_buffer + data_offset, n * 4, 
1116 8ccad811 bellard
                              ide_atapi_cmd_read_dma_cb, bm);
1117 98087450 bellard
}
1118 98087450 bellard
1119 98087450 bellard
/* start a CD-CDROM read command with DMA */
1120 98087450 bellard
/* XXX: test if DMA is available */
1121 98087450 bellard
static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
1122 98087450 bellard
                                   int sector_size)
1123 98087450 bellard
{
1124 98087450 bellard
    s->lba = lba;
1125 98087450 bellard
    s->packet_transfer_size = nb_sectors * sector_size;
1126 8ccad811 bellard
    s->io_buffer_index = 0;
1127 8ccad811 bellard
    s->io_buffer_size = 0;
1128 98087450 bellard
    s->cd_sector_size = sector_size;
1129 98087450 bellard
1130 8ccad811 bellard
    /* XXX: check if BUSY_STAT should be set */
1131 8ccad811 bellard
    s->status = READY_STAT | DRQ_STAT | BUSY_STAT;
1132 98087450 bellard
    ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
1133 98087450 bellard
}
1134 98087450 bellard
1135 98087450 bellard
static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors, 
1136 98087450 bellard
                               int sector_size)
1137 98087450 bellard
{
1138 98087450 bellard
#ifdef DEBUG_IDE_ATAPI
1139 98087450 bellard
    printf("read: LBA=%d nb_sectors=%d\n", lba, nb_sectors);
1140 98087450 bellard
#endif
1141 98087450 bellard
    if (s->atapi_dma) {
1142 98087450 bellard
        ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
1143 98087450 bellard
    } else {
1144 98087450 bellard
        ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size);
1145 98087450 bellard
    }
1146 98087450 bellard
}
1147 98087450 bellard
1148 5391d806 bellard
static void ide_atapi_cmd(IDEState *s)
1149 5391d806 bellard
{
1150 5391d806 bellard
    const uint8_t *packet;
1151 5391d806 bellard
    uint8_t *buf;
1152 5391d806 bellard
    int max_len;
1153 5391d806 bellard
1154 5391d806 bellard
    packet = s->io_buffer;
1155 5391d806 bellard
    buf = s->io_buffer;
1156 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1157 5391d806 bellard
    {
1158 5391d806 bellard
        int i;
1159 5391d806 bellard
        printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
1160 5391d806 bellard
        for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
1161 5391d806 bellard
            printf(" %02x", packet[i]);
1162 5391d806 bellard
        }
1163 5391d806 bellard
        printf("\n");
1164 5391d806 bellard
    }
1165 5391d806 bellard
#endif
1166 5391d806 bellard
    switch(s->io_buffer[0]) {
1167 5391d806 bellard
    case GPCMD_TEST_UNIT_READY:
1168 caed8802 bellard
        if (bdrv_is_inserted(s->bs)) {
1169 5391d806 bellard
            ide_atapi_cmd_ok(s);
1170 5391d806 bellard
        } else {
1171 5391d806 bellard
            ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1172 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1173 5391d806 bellard
        }
1174 5391d806 bellard
        break;
1175 5391d806 bellard
    case GPCMD_MODE_SENSE_10:
1176 5391d806 bellard
        {
1177 5391d806 bellard
            int action, code;
1178 5391d806 bellard
            max_len = ube16_to_cpu(packet + 7);
1179 5391d806 bellard
            action = packet[2] >> 6;
1180 5391d806 bellard
            code = packet[2] & 0x3f;
1181 5391d806 bellard
            switch(action) {
1182 5391d806 bellard
            case 0: /* current values */
1183 5391d806 bellard
                switch(code) {
1184 5391d806 bellard
                case 0x01: /* error recovery */
1185 5391d806 bellard
                    cpu_to_ube16(&buf[0], 16 + 6);
1186 5391d806 bellard
                    buf[2] = 0x70;
1187 5391d806 bellard
                    buf[3] = 0;
1188 5391d806 bellard
                    buf[4] = 0;
1189 5391d806 bellard
                    buf[5] = 0;
1190 5391d806 bellard
                    buf[6] = 0;
1191 5391d806 bellard
                    buf[7] = 0;
1192 5391d806 bellard
1193 5391d806 bellard
                    buf[8] = 0x01;
1194 5391d806 bellard
                    buf[9] = 0x06;
1195 5391d806 bellard
                    buf[10] = 0x00;
1196 5391d806 bellard
                    buf[11] = 0x05;
1197 5391d806 bellard
                    buf[12] = 0x00;
1198 5391d806 bellard
                    buf[13] = 0x00;
1199 5391d806 bellard
                    buf[14] = 0x00;
1200 5391d806 bellard
                    buf[15] = 0x00;
1201 5391d806 bellard
                    ide_atapi_cmd_reply(s, 16, max_len);
1202 5391d806 bellard
                    break;
1203 5391d806 bellard
                case 0x2a:
1204 5391d806 bellard
                    cpu_to_ube16(&buf[0], 28 + 6);
1205 5391d806 bellard
                    buf[2] = 0x70;
1206 5391d806 bellard
                    buf[3] = 0;
1207 5391d806 bellard
                    buf[4] = 0;
1208 5391d806 bellard
                    buf[5] = 0;
1209 5391d806 bellard
                    buf[6] = 0;
1210 5391d806 bellard
                    buf[7] = 0;
1211 5391d806 bellard
1212 5391d806 bellard
                    buf[8] = 0x2a;
1213 5391d806 bellard
                    buf[9] = 0x12;
1214 5391d806 bellard
                    buf[10] = 0x00;
1215 5391d806 bellard
                    buf[11] = 0x00;
1216 5391d806 bellard
                    
1217 5391d806 bellard
                    buf[12] = 0x70;
1218 5391d806 bellard
                    buf[13] = 3 << 5;
1219 5391d806 bellard
                    buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
1220 caed8802 bellard
                    if (bdrv_is_locked(s->bs))
1221 5391d806 bellard
                        buf[6] |= 1 << 1;
1222 5391d806 bellard
                    buf[15] = 0x00;
1223 5391d806 bellard
                    cpu_to_ube16(&buf[16], 706);
1224 5391d806 bellard
                    buf[18] = 0;
1225 5391d806 bellard
                    buf[19] = 2;
1226 5391d806 bellard
                    cpu_to_ube16(&buf[20], 512);
1227 5391d806 bellard
                    cpu_to_ube16(&buf[22], 706);
1228 5391d806 bellard
                    buf[24] = 0;
1229 5391d806 bellard
                    buf[25] = 0;
1230 5391d806 bellard
                    buf[26] = 0;
1231 5391d806 bellard
                    buf[27] = 0;
1232 5391d806 bellard
                    ide_atapi_cmd_reply(s, 28, max_len);
1233 5391d806 bellard
                    break;
1234 5391d806 bellard
                default:
1235 5391d806 bellard
                    goto error_cmd;
1236 5391d806 bellard
                }
1237 5391d806 bellard
                break;
1238 5391d806 bellard
            case 1: /* changeable values */
1239 5391d806 bellard
                goto error_cmd;
1240 5391d806 bellard
            case 2: /* default values */
1241 5391d806 bellard
                goto error_cmd;
1242 5391d806 bellard
            default:
1243 5391d806 bellard
            case 3: /* saved values */
1244 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1245 5391d806 bellard
                                    ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
1246 5391d806 bellard
                break;
1247 5391d806 bellard
            }
1248 5391d806 bellard
        }
1249 5391d806 bellard
        break;
1250 5391d806 bellard
    case GPCMD_REQUEST_SENSE:
1251 5391d806 bellard
        max_len = packet[4];
1252 5391d806 bellard
        memset(buf, 0, 18);
1253 5391d806 bellard
        buf[0] = 0x70 | (1 << 7);
1254 5391d806 bellard
        buf[2] = s->sense_key;
1255 5391d806 bellard
        buf[7] = 10;
1256 5391d806 bellard
        buf[12] = s->asc;
1257 5391d806 bellard
        ide_atapi_cmd_reply(s, 18, max_len);
1258 5391d806 bellard
        break;
1259 5391d806 bellard
    case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
1260 caed8802 bellard
        if (bdrv_is_inserted(s->bs)) {
1261 caed8802 bellard
            bdrv_set_locked(s->bs, packet[4] & 1);
1262 5391d806 bellard
            ide_atapi_cmd_ok(s);
1263 5391d806 bellard
        } else {
1264 5391d806 bellard
            ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1265 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1266 5391d806 bellard
        }
1267 5391d806 bellard
        break;
1268 5391d806 bellard
    case GPCMD_READ_10:
1269 5391d806 bellard
    case GPCMD_READ_12:
1270 5391d806 bellard
        {
1271 5391d806 bellard
            int nb_sectors, lba;
1272 5391d806 bellard
1273 caed8802 bellard
            if (!bdrv_is_inserted(s->bs)) {
1274 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1275 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1276 5391d806 bellard
                break;
1277 5391d806 bellard
            }
1278 5391d806 bellard
            if (packet[0] == GPCMD_READ_10)
1279 5391d806 bellard
                nb_sectors = ube16_to_cpu(packet + 7);
1280 5391d806 bellard
            else
1281 5391d806 bellard
                nb_sectors = ube32_to_cpu(packet + 6);
1282 5391d806 bellard
            lba = ube32_to_cpu(packet + 2);
1283 5391d806 bellard
            if (nb_sectors == 0) {
1284 5391d806 bellard
                ide_atapi_cmd_ok(s);
1285 5391d806 bellard
                break;
1286 5391d806 bellard
            }
1287 5391d806 bellard
            if (((int64_t)(lba + nb_sectors) << 2) > s->nb_sectors) {
1288 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1289 5391d806 bellard
                                    ASC_LOGICAL_BLOCK_OOR);
1290 5391d806 bellard
                break;
1291 5391d806 bellard
            }
1292 98087450 bellard
            ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1293 98087450 bellard
        }
1294 98087450 bellard
        break;
1295 98087450 bellard
    case GPCMD_READ_CD:
1296 98087450 bellard
        {
1297 98087450 bellard
            int nb_sectors, lba, transfer_request;
1298 98087450 bellard
1299 98087450 bellard
            if (!bdrv_is_inserted(s->bs)) {
1300 98087450 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1301 98087450 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1302 98087450 bellard
                break;
1303 98087450 bellard
            }
1304 98087450 bellard
            nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
1305 98087450 bellard
            lba = ube32_to_cpu(packet + 2);
1306 98087450 bellard
            if (nb_sectors == 0) {
1307 98087450 bellard
                ide_atapi_cmd_ok(s);
1308 98087450 bellard
                break;
1309 98087450 bellard
            }
1310 98087450 bellard
            if (((int64_t)(lba + nb_sectors) << 2) > s->nb_sectors) {
1311 98087450 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1312 98087450 bellard
                                    ASC_LOGICAL_BLOCK_OOR);
1313 98087450 bellard
                break;
1314 98087450 bellard
            }
1315 98087450 bellard
            transfer_request = packet[9];
1316 98087450 bellard
            switch(transfer_request & 0xf8) {
1317 98087450 bellard
            case 0x00:
1318 98087450 bellard
                /* nothing */
1319 98087450 bellard
                ide_atapi_cmd_ok(s);
1320 98087450 bellard
                break;
1321 98087450 bellard
            case 0x10:
1322 98087450 bellard
                /* normal read */
1323 98087450 bellard
                ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1324 98087450 bellard
                break;
1325 98087450 bellard
            case 0xf8:
1326 98087450 bellard
                /* read all data */
1327 98087450 bellard
                ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
1328 98087450 bellard
                break;
1329 98087450 bellard
            default:
1330 98087450 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1331 98087450 bellard
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1332 98087450 bellard
                break;
1333 98087450 bellard
            }
1334 5391d806 bellard
        }
1335 5391d806 bellard
        break;
1336 5391d806 bellard
    case GPCMD_SEEK:
1337 5391d806 bellard
        {
1338 5391d806 bellard
            int lba;
1339 caed8802 bellard
            if (!bdrv_is_inserted(s->bs)) {
1340 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1341 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1342 5391d806 bellard
                break;
1343 5391d806 bellard
            }
1344 5391d806 bellard
            lba = ube32_to_cpu(packet + 2);
1345 5391d806 bellard
            if (((int64_t)lba << 2) > s->nb_sectors) {
1346 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1347 5391d806 bellard
                                    ASC_LOGICAL_BLOCK_OOR);
1348 5391d806 bellard
                break;
1349 5391d806 bellard
            }
1350 5391d806 bellard
            ide_atapi_cmd_ok(s);
1351 5391d806 bellard
        }
1352 5391d806 bellard
        break;
1353 5391d806 bellard
    case GPCMD_START_STOP_UNIT:
1354 5391d806 bellard
        {
1355 5391d806 bellard
            int start, eject;
1356 5391d806 bellard
            start = packet[4] & 1;
1357 5391d806 bellard
            eject = (packet[4] >> 1) & 1;
1358 5391d806 bellard
            
1359 caed8802 bellard
            if (eject && !start) {
1360 caed8802 bellard
                /* eject the disk */
1361 caed8802 bellard
                bdrv_close(s->bs);
1362 caed8802 bellard
            }
1363 5391d806 bellard
            ide_atapi_cmd_ok(s);
1364 5391d806 bellard
        }
1365 5391d806 bellard
        break;
1366 5391d806 bellard
    case GPCMD_MECHANISM_STATUS:
1367 5391d806 bellard
        {
1368 5391d806 bellard
            max_len = ube16_to_cpu(packet + 8);
1369 5391d806 bellard
            cpu_to_ube16(buf, 0);
1370 5391d806 bellard
            /* no current LBA */
1371 5391d806 bellard
            buf[2] = 0;
1372 5391d806 bellard
            buf[3] = 0;
1373 5391d806 bellard
            buf[4] = 0;
1374 5391d806 bellard
            buf[5] = 1;
1375 5391d806 bellard
            cpu_to_ube16(buf + 6, 0);
1376 5391d806 bellard
            ide_atapi_cmd_reply(s, 8, max_len);
1377 5391d806 bellard
        }
1378 5391d806 bellard
        break;
1379 5391d806 bellard
    case GPCMD_READ_TOC_PMA_ATIP:
1380 5391d806 bellard
        {
1381 5391d806 bellard
            int format, msf, start_track, len;
1382 5391d806 bellard
1383 caed8802 bellard
            if (!bdrv_is_inserted(s->bs)) {
1384 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1385 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1386 5391d806 bellard
                break;
1387 5391d806 bellard
            }
1388 5391d806 bellard
            max_len = ube16_to_cpu(packet + 7);
1389 5391d806 bellard
            format = packet[9] >> 6;
1390 5391d806 bellard
            msf = (packet[1] >> 1) & 1;
1391 5391d806 bellard
            start_track = packet[6];
1392 5391d806 bellard
            switch(format) {
1393 5391d806 bellard
            case 0:
1394 2e5d83bb pbrook
                len = cdrom_read_toc(s->nb_sectors >> 2, buf, msf, start_track);
1395 5391d806 bellard
                if (len < 0)
1396 5391d806 bellard
                    goto error_cmd;
1397 5391d806 bellard
                ide_atapi_cmd_reply(s, len, max_len);
1398 5391d806 bellard
                break;
1399 5391d806 bellard
            case 1:
1400 5391d806 bellard
                /* multi session : only a single session defined */
1401 5391d806 bellard
                memset(buf, 0, 12);
1402 5391d806 bellard
                buf[1] = 0x0a;
1403 5391d806 bellard
                buf[2] = 0x01;
1404 5391d806 bellard
                buf[3] = 0x01;
1405 5391d806 bellard
                ide_atapi_cmd_reply(s, 12, max_len);
1406 5391d806 bellard
                break;
1407 98087450 bellard
            case 2:
1408 2e5d83bb pbrook
                len = cdrom_read_toc_raw(s->nb_sectors >> 2, buf, msf, start_track);
1409 98087450 bellard
                if (len < 0)
1410 98087450 bellard
                    goto error_cmd;
1411 98087450 bellard
                ide_atapi_cmd_reply(s, len, max_len);
1412 98087450 bellard
                break;
1413 5391d806 bellard
            default:
1414 7f777bf3 bellard
            error_cmd:
1415 7f777bf3 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1416 7f777bf3 bellard
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1417 7f777bf3 bellard
                break;
1418 5391d806 bellard
            }
1419 5391d806 bellard
        }
1420 5391d806 bellard
        break;
1421 5391d806 bellard
    case GPCMD_READ_CDVD_CAPACITY:
1422 caed8802 bellard
        if (!bdrv_is_inserted(s->bs)) {
1423 5391d806 bellard
            ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1424 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1425 5391d806 bellard
            break;
1426 5391d806 bellard
        }
1427 5391d806 bellard
        /* NOTE: it is really the number of sectors minus 1 */
1428 5391d806 bellard
        cpu_to_ube32(buf, (s->nb_sectors >> 2) - 1);
1429 5391d806 bellard
        cpu_to_ube32(buf + 4, 2048);
1430 5391d806 bellard
        ide_atapi_cmd_reply(s, 8, 8);
1431 5391d806 bellard
        break;
1432 bd0d90b2 bellard
    case GPCMD_INQUIRY:
1433 bd0d90b2 bellard
        max_len = packet[4];
1434 bd0d90b2 bellard
        buf[0] = 0x05; /* CD-ROM */
1435 bd0d90b2 bellard
        buf[1] = 0x80; /* removable */
1436 bd0d90b2 bellard
        buf[2] = 0x00; /* ISO */
1437 bd0d90b2 bellard
        buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
1438 bd0d90b2 bellard
        buf[4] = 31; /* additionnal length */
1439 bd0d90b2 bellard
        buf[5] = 0; /* reserved */
1440 bd0d90b2 bellard
        buf[6] = 0; /* reserved */
1441 bd0d90b2 bellard
        buf[7] = 0; /* reserved */
1442 bd0d90b2 bellard
        padstr8(buf + 8, 8, "QEMU");
1443 bd0d90b2 bellard
        padstr8(buf + 16, 16, "QEMU CD-ROM");
1444 bd0d90b2 bellard
        padstr8(buf + 32, 4, QEMU_VERSION);
1445 bd0d90b2 bellard
        ide_atapi_cmd_reply(s, 36, max_len);
1446 bd0d90b2 bellard
        break;
1447 5391d806 bellard
    default:
1448 5391d806 bellard
        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1449 7f777bf3 bellard
                            ASC_ILLEGAL_OPCODE);
1450 5391d806 bellard
        break;
1451 5391d806 bellard
    }
1452 5391d806 bellard
}
1453 5391d806 bellard
1454 caed8802 bellard
/* called when the inserted state of the media has changed */
1455 caed8802 bellard
static void cdrom_change_cb(void *opaque)
1456 5391d806 bellard
{
1457 caed8802 bellard
    IDEState *s = opaque;
1458 caed8802 bellard
    int64_t nb_sectors;
1459 caed8802 bellard
1460 caed8802 bellard
    /* XXX: send interrupt too */
1461 caed8802 bellard
    bdrv_get_geometry(s->bs, &nb_sectors);
1462 caed8802 bellard
    s->nb_sectors = nb_sectors;
1463 caed8802 bellard
}
1464 caed8802 bellard
1465 c2ff060f bellard
static void ide_cmd_lba48_transform(IDEState *s, int lba48)
1466 c2ff060f bellard
{
1467 c2ff060f bellard
    s->lba48 = lba48;
1468 c2ff060f bellard
1469 c2ff060f bellard
    /* handle the 'magic' 0 nsector count conversion here. to avoid
1470 c2ff060f bellard
     * fiddling with the rest of the read logic, we just store the
1471 c2ff060f bellard
     * full sector count in ->nsector and ignore ->hob_nsector from now
1472 c2ff060f bellard
     */
1473 c2ff060f bellard
    if (!s->lba48) {
1474 c2ff060f bellard
        if (!s->nsector)
1475 c2ff060f bellard
            s->nsector = 256;
1476 c2ff060f bellard
    } else {
1477 c2ff060f bellard
        if (!s->nsector && !s->hob_nsector)
1478 c2ff060f bellard
            s->nsector = 65536;
1479 c2ff060f bellard
        else {
1480 c2ff060f bellard
            int lo = s->nsector;
1481 c2ff060f bellard
            int hi = s->hob_nsector;
1482 c2ff060f bellard
1483 c2ff060f bellard
            s->nsector = (hi << 8) | lo;
1484 c2ff060f bellard
        }
1485 c2ff060f bellard
    }
1486 c2ff060f bellard
}
1487 c2ff060f bellard
1488 c2ff060f bellard
static void ide_clear_hob(IDEState *ide_if)
1489 c2ff060f bellard
{
1490 c2ff060f bellard
    /* any write clears HOB high bit of device control register */
1491 c2ff060f bellard
    ide_if[0].select &= ~(1 << 7);
1492 c2ff060f bellard
    ide_if[1].select &= ~(1 << 7);
1493 c2ff060f bellard
}
1494 c2ff060f bellard
1495 caed8802 bellard
static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1496 caed8802 bellard
{
1497 caed8802 bellard
    IDEState *ide_if = opaque;
1498 c45c3d00 bellard
    IDEState *s;
1499 5391d806 bellard
    int unit, n;
1500 c2ff060f bellard
    int lba48 = 0;
1501 5391d806 bellard
1502 5391d806 bellard
#ifdef DEBUG_IDE
1503 5391d806 bellard
    printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);
1504 5391d806 bellard
#endif
1505 c2ff060f bellard
1506 5391d806 bellard
    addr &= 7;
1507 5391d806 bellard
    switch(addr) {
1508 5391d806 bellard
    case 0:
1509 5391d806 bellard
        break;
1510 5391d806 bellard
    case 1:
1511 c2ff060f bellard
        ide_clear_hob(ide_if);
1512 c45c3d00 bellard
        /* NOTE: data is written to the two drives */
1513 c2ff060f bellard
        ide_if[0].hob_feature = ide_if[0].feature;
1514 c2ff060f bellard
        ide_if[1].hob_feature = ide_if[1].feature;
1515 c45c3d00 bellard
        ide_if[0].feature = val;
1516 c45c3d00 bellard
        ide_if[1].feature = val;
1517 5391d806 bellard
        break;
1518 5391d806 bellard
    case 2:
1519 c2ff060f bellard
        ide_clear_hob(ide_if);
1520 c2ff060f bellard
        ide_if[0].hob_nsector = ide_if[0].nsector;
1521 c2ff060f bellard
        ide_if[1].hob_nsector = ide_if[1].nsector;
1522 c45c3d00 bellard
        ide_if[0].nsector = val;
1523 c45c3d00 bellard
        ide_if[1].nsector = val;
1524 5391d806 bellard
        break;
1525 5391d806 bellard
    case 3:
1526 c2ff060f bellard
        ide_clear_hob(ide_if);
1527 c2ff060f bellard
        ide_if[0].hob_sector = ide_if[0].sector;
1528 c2ff060f bellard
        ide_if[1].hob_sector = ide_if[1].sector;
1529 c45c3d00 bellard
        ide_if[0].sector = val;
1530 c45c3d00 bellard
        ide_if[1].sector = val;
1531 5391d806 bellard
        break;
1532 5391d806 bellard
    case 4:
1533 c2ff060f bellard
        ide_clear_hob(ide_if);
1534 c2ff060f bellard
        ide_if[0].hob_lcyl = ide_if[0].lcyl;
1535 c2ff060f bellard
        ide_if[1].hob_lcyl = ide_if[1].lcyl;
1536 c45c3d00 bellard
        ide_if[0].lcyl = val;
1537 c45c3d00 bellard
        ide_if[1].lcyl = val;
1538 5391d806 bellard
        break;
1539 5391d806 bellard
    case 5:
1540 c2ff060f bellard
        ide_clear_hob(ide_if);
1541 c2ff060f bellard
        ide_if[0].hob_hcyl = ide_if[0].hcyl;
1542 c2ff060f bellard
        ide_if[1].hob_hcyl = ide_if[1].hcyl;
1543 c45c3d00 bellard
        ide_if[0].hcyl = val;
1544 c45c3d00 bellard
        ide_if[1].hcyl = val;
1545 5391d806 bellard
        break;
1546 5391d806 bellard
    case 6:
1547 c2ff060f bellard
        /* FIXME: HOB readback uses bit 7 */
1548 7ae98627 bellard
        ide_if[0].select = (val & ~0x10) | 0xa0;
1549 7ae98627 bellard
        ide_if[1].select = (val | 0x10) | 0xa0;
1550 5391d806 bellard
        /* select drive */
1551 5391d806 bellard
        unit = (val >> 4) & 1;
1552 5391d806 bellard
        s = ide_if + unit;
1553 5391d806 bellard
        ide_if->cur_drive = s;
1554 5391d806 bellard
        break;
1555 5391d806 bellard
    default:
1556 5391d806 bellard
    case 7:
1557 5391d806 bellard
        /* command */
1558 5391d806 bellard
#if defined(DEBUG_IDE)
1559 5391d806 bellard
        printf("ide: CMD=%02x\n", val);
1560 5391d806 bellard
#endif
1561 c45c3d00 bellard
        s = ide_if->cur_drive;
1562 66201e2d bellard
        /* ignore commands to non existant slave */
1563 66201e2d bellard
        if (s != ide_if && !s->bs) 
1564 66201e2d bellard
            break;
1565 c2ff060f bellard
1566 5391d806 bellard
        switch(val) {
1567 5391d806 bellard
        case WIN_IDENTIFY:
1568 5391d806 bellard
            if (s->bs && !s->is_cdrom) {
1569 5391d806 bellard
                ide_identify(s);
1570 2a282056 bellard
                s->status = READY_STAT | SEEK_STAT;
1571 5391d806 bellard
                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1572 5391d806 bellard
            } else {
1573 5391d806 bellard
                if (s->is_cdrom) {
1574 5391d806 bellard
                    ide_set_signature(s);
1575 5391d806 bellard
                }
1576 5391d806 bellard
                ide_abort_command(s);
1577 5391d806 bellard
            }
1578 5391d806 bellard
            ide_set_irq(s);
1579 5391d806 bellard
            break;
1580 5391d806 bellard
        case WIN_SPECIFY:
1581 5391d806 bellard
        case WIN_RECAL:
1582 a136e5a8 bellard
            s->error = 0;
1583 769bec72 bellard
            s->status = READY_STAT | SEEK_STAT;
1584 5391d806 bellard
            ide_set_irq(s);
1585 5391d806 bellard
            break;
1586 5391d806 bellard
        case WIN_SETMULT:
1587 5391d806 bellard
            if (s->nsector > MAX_MULT_SECTORS || 
1588 5391d806 bellard
                s->nsector == 0 ||
1589 5391d806 bellard
                (s->nsector & (s->nsector - 1)) != 0) {
1590 5391d806 bellard
                ide_abort_command(s);
1591 5391d806 bellard
            } else {
1592 5391d806 bellard
                s->mult_sectors = s->nsector;
1593 5391d806 bellard
                s->status = READY_STAT;
1594 5391d806 bellard
            }
1595 5391d806 bellard
            ide_set_irq(s);
1596 5391d806 bellard
            break;
1597 c2ff060f bellard
        case WIN_VERIFY_EXT:
1598 c2ff060f bellard
            lba48 = 1;
1599 4ce900b4 bellard
        case WIN_VERIFY:
1600 4ce900b4 bellard
        case WIN_VERIFY_ONCE:
1601 4ce900b4 bellard
            /* do sector number check ? */
1602 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1603 4ce900b4 bellard
            s->status = READY_STAT;
1604 4ce900b4 bellard
            ide_set_irq(s);
1605 4ce900b4 bellard
            break;
1606 c2ff060f bellard
        case WIN_READ_EXT:
1607 c2ff060f bellard
            lba48 = 1;
1608 5391d806 bellard
        case WIN_READ:
1609 5391d806 bellard
        case WIN_READ_ONCE:
1610 6b136f9e bellard
            if (!s->bs) 
1611 6b136f9e bellard
                goto abort_cmd;
1612 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1613 5391d806 bellard
            s->req_nb_sectors = 1;
1614 5391d806 bellard
            ide_sector_read(s);
1615 5391d806 bellard
            break;
1616 c2ff060f bellard
        case WIN_WRITE_EXT:
1617 c2ff060f bellard
            lba48 = 1;
1618 5391d806 bellard
        case WIN_WRITE:
1619 5391d806 bellard
        case WIN_WRITE_ONCE:
1620 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1621 a136e5a8 bellard
            s->error = 0;
1622 f66723fa bellard
            s->status = SEEK_STAT | READY_STAT;
1623 5391d806 bellard
            s->req_nb_sectors = 1;
1624 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
1625 5391d806 bellard
            break;
1626 c2ff060f bellard
        case WIN_MULTREAD_EXT:
1627 c2ff060f bellard
            lba48 = 1;
1628 5391d806 bellard
        case WIN_MULTREAD:
1629 5391d806 bellard
            if (!s->mult_sectors)
1630 5391d806 bellard
                goto abort_cmd;
1631 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1632 5391d806 bellard
            s->req_nb_sectors = s->mult_sectors;
1633 5391d806 bellard
            ide_sector_read(s);
1634 5391d806 bellard
            break;
1635 c2ff060f bellard
        case WIN_MULTWRITE_EXT:
1636 c2ff060f bellard
            lba48 = 1;
1637 5391d806 bellard
        case WIN_MULTWRITE:
1638 5391d806 bellard
            if (!s->mult_sectors)
1639 5391d806 bellard
                goto abort_cmd;
1640 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1641 a136e5a8 bellard
            s->error = 0;
1642 f66723fa bellard
            s->status = SEEK_STAT | READY_STAT;
1643 5391d806 bellard
            s->req_nb_sectors = s->mult_sectors;
1644 5391d806 bellard
            n = s->nsector;
1645 5391d806 bellard
            if (n > s->req_nb_sectors)
1646 5391d806 bellard
                n = s->req_nb_sectors;
1647 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
1648 5391d806 bellard
            break;
1649 c2ff060f bellard
        case WIN_READDMA_EXT:
1650 c2ff060f bellard
            lba48 = 1;
1651 98087450 bellard
        case WIN_READDMA:
1652 98087450 bellard
        case WIN_READDMA_ONCE:
1653 98087450 bellard
            if (!s->bs) 
1654 98087450 bellard
                goto abort_cmd;
1655 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1656 98087450 bellard
            ide_sector_read_dma(s);
1657 98087450 bellard
            break;
1658 c2ff060f bellard
        case WIN_WRITEDMA_EXT:
1659 c2ff060f bellard
            lba48 = 1;
1660 98087450 bellard
        case WIN_WRITEDMA:
1661 98087450 bellard
        case WIN_WRITEDMA_ONCE:
1662 98087450 bellard
            if (!s->bs) 
1663 98087450 bellard
                goto abort_cmd;
1664 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1665 98087450 bellard
            ide_sector_write_dma(s);
1666 98087450 bellard
            break;
1667 c2ff060f bellard
        case WIN_READ_NATIVE_MAX_EXT:
1668 c2ff060f bellard
            lba48 = 1;
1669 5391d806 bellard
        case WIN_READ_NATIVE_MAX:
1670 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1671 5391d806 bellard
            ide_set_sector(s, s->nb_sectors - 1);
1672 5391d806 bellard
            s->status = READY_STAT;
1673 5391d806 bellard
            ide_set_irq(s);
1674 5391d806 bellard
            break;
1675 a136e5a8 bellard
        case WIN_CHECKPOWERMODE1:
1676 a136e5a8 bellard
            s->nsector = 0xff; /* device active or idle */
1677 a136e5a8 bellard
            s->status = READY_STAT;
1678 a136e5a8 bellard
            ide_set_irq(s);
1679 a136e5a8 bellard
            break;
1680 34e538ae bellard
        case WIN_SETFEATURES:
1681 34e538ae bellard
            if (!s->bs)
1682 34e538ae bellard
                goto abort_cmd;
1683 34e538ae bellard
            /* XXX: valid for CDROM ? */
1684 34e538ae bellard
            switch(s->feature) {
1685 34e538ae bellard
            case 0x02: /* write cache enable */
1686 34e538ae bellard
            case 0x82: /* write cache disable */
1687 34e538ae bellard
            case 0xaa: /* read look-ahead enable */
1688 34e538ae bellard
            case 0x55: /* read look-ahead disable */
1689 e0fe67aa bellard
                s->status = READY_STAT | SEEK_STAT;
1690 34e538ae bellard
                ide_set_irq(s);
1691 34e538ae bellard
                break;
1692 94458802 bellard
            case 0x03: { /* set transfer mode */
1693 94458802 bellard
                uint8_t val = s->nsector & 0x07;
1694 94458802 bellard
1695 94458802 bellard
                switch (s->nsector >> 3) {
1696 94458802 bellard
                    case 0x00: /* pio default */
1697 94458802 bellard
                    case 0x01: /* pio mode */
1698 94458802 bellard
                        put_le16(s->identify_data + 63,0x07);
1699 94458802 bellard
                        put_le16(s->identify_data + 88,0x3f);
1700 94458802 bellard
                        break;
1701 94458802 bellard
                    case 0x04: /* mdma mode */
1702 94458802 bellard
                        put_le16(s->identify_data + 63,0x07 | (1 << (val + 8)));
1703 94458802 bellard
                        put_le16(s->identify_data + 88,0x3f);
1704 94458802 bellard
                        break;
1705 94458802 bellard
                    case 0x08: /* udma mode */
1706 94458802 bellard
                        put_le16(s->identify_data + 63,0x07);
1707 94458802 bellard
                        put_le16(s->identify_data + 88,0x3f | (1 << (val + 8)));
1708 94458802 bellard
                        break;
1709 94458802 bellard
                    default:
1710 94458802 bellard
                        goto abort_cmd;
1711 94458802 bellard
                }
1712 94458802 bellard
                s->status = READY_STAT | SEEK_STAT;
1713 94458802 bellard
                ide_set_irq(s);
1714 94458802 bellard
                break;
1715 94458802 bellard
            }
1716 34e538ae bellard
            default:
1717 34e538ae bellard
                goto abort_cmd;
1718 34e538ae bellard
            }
1719 34e538ae bellard
            break;
1720 c2ff060f bellard
        case WIN_FLUSH_CACHE:
1721 c2ff060f bellard
        case WIN_FLUSH_CACHE_EXT:
1722 7a6cba61 pbrook
            if (s->bs)
1723 7a6cba61 pbrook
                bdrv_flush(s->bs);
1724 7a6cba61 pbrook
            s->status = READY_STAT;
1725 7a6cba61 pbrook
            ide_set_irq(s);
1726 7a6cba61 pbrook
            break;
1727 a7dfe172 bellard
        case WIN_STANDBYNOW1:
1728 c451ee71 bellard
        case WIN_IDLEIMMEDIATE:
1729 a7dfe172 bellard
            s->status = READY_STAT;
1730 a7dfe172 bellard
            ide_set_irq(s);
1731 a7dfe172 bellard
            break;
1732 5391d806 bellard
            /* ATAPI commands */
1733 5391d806 bellard
        case WIN_PIDENTIFY:
1734 5391d806 bellard
            if (s->is_cdrom) {
1735 5391d806 bellard
                ide_atapi_identify(s);
1736 1298fe63 bellard
                s->status = READY_STAT | SEEK_STAT;
1737 5391d806 bellard
                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1738 5391d806 bellard
            } else {
1739 5391d806 bellard
                ide_abort_command(s);
1740 5391d806 bellard
            }
1741 5391d806 bellard
            ide_set_irq(s);
1742 5391d806 bellard
            break;
1743 c451ee71 bellard
        case WIN_DIAGNOSE:
1744 c451ee71 bellard
            ide_set_signature(s);
1745 c451ee71 bellard
            s->status = 0x00; /* NOTE: READY is _not_ set */
1746 c451ee71 bellard
            s->error = 0x01;
1747 c451ee71 bellard
            break;
1748 5391d806 bellard
        case WIN_SRST:
1749 5391d806 bellard
            if (!s->is_cdrom)
1750 5391d806 bellard
                goto abort_cmd;
1751 5391d806 bellard
            ide_set_signature(s);
1752 6b136f9e bellard
            s->status = 0x00; /* NOTE: READY is _not_ set */
1753 5391d806 bellard
            s->error = 0x01;
1754 5391d806 bellard
            break;
1755 5391d806 bellard
        case WIN_PACKETCMD:
1756 5391d806 bellard
            if (!s->is_cdrom)
1757 5391d806 bellard
                goto abort_cmd;
1758 98087450 bellard
            /* overlapping commands not supported */
1759 98087450 bellard
            if (s->feature & 0x02)
1760 5391d806 bellard
                goto abort_cmd;
1761 98087450 bellard
            s->atapi_dma = s->feature & 1;
1762 5391d806 bellard
            s->nsector = 1;
1763 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE, 
1764 5391d806 bellard
                               ide_atapi_cmd);
1765 5391d806 bellard
            break;
1766 5391d806 bellard
        default:
1767 5391d806 bellard
        abort_cmd:
1768 5391d806 bellard
            ide_abort_command(s);
1769 5391d806 bellard
            ide_set_irq(s);
1770 5391d806 bellard
            break;
1771 5391d806 bellard
        }
1772 5391d806 bellard
    }
1773 5391d806 bellard
}
1774 5391d806 bellard
1775 caed8802 bellard
static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
1776 5391d806 bellard
{
1777 7ae98627 bellard
    IDEState *ide_if = opaque;
1778 7ae98627 bellard
    IDEState *s = ide_if->cur_drive;
1779 5391d806 bellard
    uint32_t addr;
1780 c2ff060f bellard
    int ret, hob;
1781 5391d806 bellard
1782 5391d806 bellard
    addr = addr1 & 7;
1783 c2ff060f bellard
    /* FIXME: HOB readback uses bit 7, but it's always set right now */
1784 c2ff060f bellard
    //hob = s->select & (1 << 7);
1785 c2ff060f bellard
    hob = 0;
1786 5391d806 bellard
    switch(addr) {
1787 5391d806 bellard
    case 0:
1788 5391d806 bellard
        ret = 0xff;
1789 5391d806 bellard
        break;
1790 5391d806 bellard
    case 1:
1791 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1792 c45c3d00 bellard
            ret = 0;
1793 c2ff060f bellard
        else if (!hob)
1794 c45c3d00 bellard
            ret = s->error;
1795 c2ff060f bellard
        else
1796 c2ff060f bellard
            ret = s->hob_feature;
1797 5391d806 bellard
        break;
1798 5391d806 bellard
    case 2:
1799 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1800 c45c3d00 bellard
            ret = 0;
1801 c2ff060f bellard
        else if (!hob)
1802 c45c3d00 bellard
            ret = s->nsector & 0xff;
1803 c2ff060f bellard
        else
1804 c2ff060f bellard
            ret = s->hob_nsector;
1805 5391d806 bellard
        break;
1806 5391d806 bellard
    case 3:
1807 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1808 c45c3d00 bellard
            ret = 0;
1809 c2ff060f bellard
        else if (!hob)
1810 c45c3d00 bellard
            ret = s->sector;
1811 c2ff060f bellard
        else
1812 c2ff060f bellard
            ret = s->hob_sector;
1813 5391d806 bellard
        break;
1814 5391d806 bellard
    case 4:
1815 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1816 c45c3d00 bellard
            ret = 0;
1817 c2ff060f bellard
        else if (!hob)
1818 c45c3d00 bellard
            ret = s->lcyl;
1819 c2ff060f bellard
        else
1820 c2ff060f bellard
            ret = s->hob_lcyl;
1821 5391d806 bellard
        break;
1822 5391d806 bellard
    case 5:
1823 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1824 c45c3d00 bellard
            ret = 0;
1825 c2ff060f bellard
        else if (!hob)
1826 c45c3d00 bellard
            ret = s->hcyl;
1827 c2ff060f bellard
        else
1828 c2ff060f bellard
            ret = s->hob_hcyl;
1829 5391d806 bellard
        break;
1830 5391d806 bellard
    case 6:
1831 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1832 c45c3d00 bellard
            ret = 0;
1833 c45c3d00 bellard
        else
1834 7ae98627 bellard
            ret = s->select;
1835 5391d806 bellard
        break;
1836 5391d806 bellard
    default:
1837 5391d806 bellard
    case 7:
1838 66201e2d bellard
        if ((!ide_if[0].bs && !ide_if[1].bs) ||
1839 66201e2d bellard
            (s != ide_if && !s->bs))
1840 c45c3d00 bellard
            ret = 0;
1841 c45c3d00 bellard
        else
1842 c45c3d00 bellard
            ret = s->status;
1843 5457c8ce bellard
        s->set_irq(s->irq_opaque, s->irq, 0);
1844 5391d806 bellard
        break;
1845 5391d806 bellard
    }
1846 5391d806 bellard
#ifdef DEBUG_IDE
1847 5391d806 bellard
    printf("ide: read addr=0x%x val=%02x\n", addr1, ret);
1848 5391d806 bellard
#endif
1849 5391d806 bellard
    return ret;
1850 5391d806 bellard
}
1851 5391d806 bellard
1852 caed8802 bellard
static uint32_t ide_status_read(void *opaque, uint32_t addr)
1853 5391d806 bellard
{
1854 7ae98627 bellard
    IDEState *ide_if = opaque;
1855 7ae98627 bellard
    IDEState *s = ide_if->cur_drive;
1856 5391d806 bellard
    int ret;
1857 7ae98627 bellard
1858 66201e2d bellard
    if ((!ide_if[0].bs && !ide_if[1].bs) ||
1859 66201e2d bellard
        (s != ide_if && !s->bs))
1860 7ae98627 bellard
        ret = 0;
1861 7ae98627 bellard
    else
1862 7ae98627 bellard
        ret = s->status;
1863 5391d806 bellard
#ifdef DEBUG_IDE
1864 5391d806 bellard
    printf("ide: read status addr=0x%x val=%02x\n", addr, ret);
1865 5391d806 bellard
#endif
1866 5391d806 bellard
    return ret;
1867 5391d806 bellard
}
1868 5391d806 bellard
1869 caed8802 bellard
static void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
1870 5391d806 bellard
{
1871 caed8802 bellard
    IDEState *ide_if = opaque;
1872 5391d806 bellard
    IDEState *s;
1873 5391d806 bellard
    int i;
1874 5391d806 bellard
1875 5391d806 bellard
#ifdef DEBUG_IDE
1876 5391d806 bellard
    printf("ide: write control addr=0x%x val=%02x\n", addr, val);
1877 5391d806 bellard
#endif
1878 5391d806 bellard
    /* common for both drives */
1879 5391d806 bellard
    if (!(ide_if[0].cmd & IDE_CMD_RESET) &&
1880 5391d806 bellard
        (val & IDE_CMD_RESET)) {
1881 5391d806 bellard
        /* reset low to high */
1882 5391d806 bellard
        for(i = 0;i < 2; i++) {
1883 5391d806 bellard
            s = &ide_if[i];
1884 5391d806 bellard
            s->status = BUSY_STAT | SEEK_STAT;
1885 5391d806 bellard
            s->error = 0x01;
1886 5391d806 bellard
        }
1887 5391d806 bellard
    } else if ((ide_if[0].cmd & IDE_CMD_RESET) &&
1888 5391d806 bellard
               !(val & IDE_CMD_RESET)) {
1889 5391d806 bellard
        /* high to low */
1890 5391d806 bellard
        for(i = 0;i < 2; i++) {
1891 5391d806 bellard
            s = &ide_if[i];
1892 6b136f9e bellard
            if (s->is_cdrom)
1893 6b136f9e bellard
                s->status = 0x00; /* NOTE: READY is _not_ set */
1894 6b136f9e bellard
            else
1895 56bf1d37 bellard
                s->status = READY_STAT | SEEK_STAT;
1896 5391d806 bellard
            ide_set_signature(s);
1897 5391d806 bellard
        }
1898 5391d806 bellard
    }
1899 5391d806 bellard
1900 5391d806 bellard
    ide_if[0].cmd = val;
1901 5391d806 bellard
    ide_if[1].cmd = val;
1902 5391d806 bellard
}
1903 5391d806 bellard
1904 caed8802 bellard
static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
1905 5391d806 bellard
{
1906 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1907 5391d806 bellard
    uint8_t *p;
1908 5391d806 bellard
1909 5391d806 bellard
    p = s->data_ptr;
1910 0c4ad8dc bellard
    *(uint16_t *)p = le16_to_cpu(val);
1911 5391d806 bellard
    p += 2;
1912 5391d806 bellard
    s->data_ptr = p;
1913 5391d806 bellard
    if (p >= s->data_end)
1914 5391d806 bellard
        s->end_transfer_func(s);
1915 5391d806 bellard
}
1916 5391d806 bellard
1917 caed8802 bellard
static uint32_t ide_data_readw(void *opaque, uint32_t addr)
1918 5391d806 bellard
{
1919 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1920 5391d806 bellard
    uint8_t *p;
1921 5391d806 bellard
    int ret;
1922 5391d806 bellard
    p = s->data_ptr;
1923 0c4ad8dc bellard
    ret = cpu_to_le16(*(uint16_t *)p);
1924 5391d806 bellard
    p += 2;
1925 5391d806 bellard
    s->data_ptr = p;
1926 5391d806 bellard
    if (p >= s->data_end)
1927 5391d806 bellard
        s->end_transfer_func(s);
1928 5391d806 bellard
    return ret;
1929 5391d806 bellard
}
1930 5391d806 bellard
1931 caed8802 bellard
static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
1932 5391d806 bellard
{
1933 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1934 5391d806 bellard
    uint8_t *p;
1935 5391d806 bellard
1936 5391d806 bellard
    p = s->data_ptr;
1937 0c4ad8dc bellard
    *(uint32_t *)p = le32_to_cpu(val);
1938 5391d806 bellard
    p += 4;
1939 5391d806 bellard
    s->data_ptr = p;
1940 5391d806 bellard
    if (p >= s->data_end)
1941 5391d806 bellard
        s->end_transfer_func(s);
1942 5391d806 bellard
}
1943 5391d806 bellard
1944 caed8802 bellard
static uint32_t ide_data_readl(void *opaque, uint32_t addr)
1945 5391d806 bellard
{
1946 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1947 5391d806 bellard
    uint8_t *p;
1948 5391d806 bellard
    int ret;
1949 5391d806 bellard
    
1950 5391d806 bellard
    p = s->data_ptr;
1951 0c4ad8dc bellard
    ret = cpu_to_le32(*(uint32_t *)p);
1952 5391d806 bellard
    p += 4;
1953 5391d806 bellard
    s->data_ptr = p;
1954 5391d806 bellard
    if (p >= s->data_end)
1955 5391d806 bellard
        s->end_transfer_func(s);
1956 5391d806 bellard
    return ret;
1957 5391d806 bellard
}
1958 5391d806 bellard
1959 a7dfe172 bellard
static void ide_dummy_transfer_stop(IDEState *s)
1960 a7dfe172 bellard
{
1961 a7dfe172 bellard
    s->data_ptr = s->io_buffer;
1962 a7dfe172 bellard
    s->data_end = s->io_buffer;
1963 a7dfe172 bellard
    s->io_buffer[0] = 0xff;
1964 a7dfe172 bellard
    s->io_buffer[1] = 0xff;
1965 a7dfe172 bellard
    s->io_buffer[2] = 0xff;
1966 a7dfe172 bellard
    s->io_buffer[3] = 0xff;
1967 a7dfe172 bellard
}
1968 a7dfe172 bellard
1969 5391d806 bellard
static void ide_reset(IDEState *s)
1970 5391d806 bellard
{
1971 5391d806 bellard
    s->mult_sectors = MAX_MULT_SECTORS;
1972 5391d806 bellard
    s->cur_drive = s;
1973 5391d806 bellard
    s->select = 0xa0;
1974 5391d806 bellard
    s->status = READY_STAT;
1975 5391d806 bellard
    ide_set_signature(s);
1976 a7dfe172 bellard
    /* init the transfer handler so that 0xffff is returned on data
1977 a7dfe172 bellard
       accesses */
1978 a7dfe172 bellard
    s->end_transfer_func = ide_dummy_transfer_stop;
1979 a7dfe172 bellard
    ide_dummy_transfer_stop(s);
1980 5391d806 bellard
}
1981 5391d806 bellard
1982 5391d806 bellard
struct partition {
1983 5391d806 bellard
        uint8_t boot_ind;                /* 0x80 - active */
1984 5391d806 bellard
        uint8_t head;                /* starting head */
1985 5391d806 bellard
        uint8_t sector;                /* starting sector */
1986 5391d806 bellard
        uint8_t cyl;                /* starting cylinder */
1987 5391d806 bellard
        uint8_t sys_ind;                /* What partition type */
1988 5391d806 bellard
        uint8_t end_head;                /* end head */
1989 5391d806 bellard
        uint8_t end_sector;        /* end sector */
1990 5391d806 bellard
        uint8_t end_cyl;                /* end cylinder */
1991 5391d806 bellard
        uint32_t start_sect;        /* starting sector counting from 0 */
1992 5391d806 bellard
        uint32_t nr_sects;                /* nr of sectors in partition */
1993 5391d806 bellard
} __attribute__((packed));
1994 5391d806 bellard
1995 bf1b938f bellard
/* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
1996 bf1b938f bellard
static int guess_disk_lchs(IDEState *s, 
1997 bf1b938f bellard
                           int *pcylinders, int *pheads, int *psectors)
1998 5391d806 bellard
{
1999 5391d806 bellard
    uint8_t buf[512];
2000 46d4767d bellard
    int ret, i, heads, sectors, cylinders;
2001 5391d806 bellard
    struct partition *p;
2002 5391d806 bellard
    uint32_t nr_sects;
2003 5391d806 bellard
2004 5391d806 bellard
    ret = bdrv_read(s->bs, 0, buf, 1);
2005 5391d806 bellard
    if (ret < 0)
2006 bf1b938f bellard
        return -1;
2007 5391d806 bellard
    /* test msdos magic */
2008 5391d806 bellard
    if (buf[510] != 0x55 || buf[511] != 0xaa)
2009 bf1b938f bellard
        return -1;
2010 5391d806 bellard
    for(i = 0; i < 4; i++) {
2011 5391d806 bellard
        p = ((struct partition *)(buf + 0x1be)) + i;
2012 0c4ad8dc bellard
        nr_sects = le32_to_cpu(p->nr_sects);
2013 5391d806 bellard
        if (nr_sects && p->end_head) {
2014 5391d806 bellard
            /* We make the assumption that the partition terminates on
2015 5391d806 bellard
               a cylinder boundary */
2016 46d4767d bellard
            heads = p->end_head + 1;
2017 46d4767d bellard
            sectors = p->end_sector & 63;
2018 46d4767d bellard
            if (sectors == 0)
2019 46d4767d bellard
                continue;
2020 46d4767d bellard
            cylinders = s->nb_sectors / (heads * sectors);
2021 46d4767d bellard
            if (cylinders < 1 || cylinders > 16383)
2022 46d4767d bellard
                continue;
2023 bf1b938f bellard
            *pheads = heads;
2024 bf1b938f bellard
            *psectors = sectors;
2025 bf1b938f bellard
            *pcylinders = cylinders;
2026 5391d806 bellard
#if 0
2027 bf1b938f bellard
            printf("guessed geometry: LCHS=%d %d %d\n", 
2028 bf1b938f bellard
                   cylinders, heads, sectors);
2029 5391d806 bellard
#endif
2030 bf1b938f bellard
            return 0;
2031 5391d806 bellard
        }
2032 5391d806 bellard
    }
2033 bf1b938f bellard
    return -1;
2034 5391d806 bellard
}
2035 5391d806 bellard
2036 5457c8ce bellard
static void ide_init2(IDEState *ide_state,
2037 5457c8ce bellard
                      BlockDriverState *hd0, BlockDriverState *hd1,
2038 5457c8ce bellard
                      SetIRQFunc *set_irq, void *irq_opaque, int irq)
2039 5391d806 bellard
{
2040 69b91039 bellard
    IDEState *s;
2041 aedf5382 bellard
    static int drive_serial = 1;
2042 bf1b938f bellard
    int i, cylinders, heads, secs, translation;
2043 5391d806 bellard
    int64_t nb_sectors;
2044 5391d806 bellard
2045 caed8802 bellard
    for(i = 0; i < 2; i++) {
2046 caed8802 bellard
        s = ide_state + i;
2047 caed8802 bellard
        if (i == 0)
2048 caed8802 bellard
            s->bs = hd0;
2049 caed8802 bellard
        else
2050 caed8802 bellard
            s->bs = hd1;
2051 5391d806 bellard
        if (s->bs) {
2052 5391d806 bellard
            bdrv_get_geometry(s->bs, &nb_sectors);
2053 5391d806 bellard
            s->nb_sectors = nb_sectors;
2054 caed8802 bellard
            /* if a geometry hint is available, use it */
2055 caed8802 bellard
            bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
2056 caed8802 bellard
            if (cylinders != 0) {
2057 5391d806 bellard
                s->cylinders = cylinders;
2058 caed8802 bellard
                s->heads = heads;
2059 caed8802 bellard
                s->sectors = secs;
2060 caed8802 bellard
            } else {
2061 bf1b938f bellard
                if (guess_disk_lchs(s, &cylinders, &heads, &secs) == 0) {
2062 bf1b938f bellard
                    if (heads > 16) {
2063 bf1b938f bellard
                        /* if heads > 16, it means that a BIOS LBA
2064 bf1b938f bellard
                           translation was active, so the default
2065 bf1b938f bellard
                           hardware geometry is OK */
2066 bf1b938f bellard
                        goto default_geometry;
2067 bf1b938f bellard
                    } else {
2068 bf1b938f bellard
                        s->cylinders = cylinders;
2069 bf1b938f bellard
                        s->heads = heads;
2070 bf1b938f bellard
                        s->sectors = secs;
2071 bf1b938f bellard
                        /* disable any translation to be in sync with
2072 bf1b938f bellard
                           the logical geometry */
2073 bf1b938f bellard
                        translation = bdrv_get_translation_hint(s->bs);
2074 bf1b938f bellard
                        if (translation == BIOS_ATA_TRANSLATION_AUTO) {
2075 bf1b938f bellard
                            bdrv_set_translation_hint(s->bs,
2076 bf1b938f bellard
                                                      BIOS_ATA_TRANSLATION_NONE);
2077 bf1b938f bellard
                        }
2078 bf1b938f bellard
                    }
2079 bf1b938f bellard
                } else {
2080 bf1b938f bellard
                default_geometry:
2081 46d4767d bellard
                    /* if no geometry, use a standard physical disk geometry */
2082 caed8802 bellard
                    cylinders = nb_sectors / (16 * 63);
2083 caed8802 bellard
                    if (cylinders > 16383)
2084 caed8802 bellard
                        cylinders = 16383;
2085 caed8802 bellard
                    else if (cylinders < 2)
2086 caed8802 bellard
                        cylinders = 2;
2087 caed8802 bellard
                    s->cylinders = cylinders;
2088 caed8802 bellard
                    s->heads = 16;
2089 caed8802 bellard
                    s->sectors = 63;
2090 caed8802 bellard
                }
2091 769bec72 bellard
                bdrv_set_geometry_hint(s->bs, s->cylinders, s->heads, s->sectors);
2092 caed8802 bellard
            }
2093 caed8802 bellard
            if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
2094 caed8802 bellard
                s->is_cdrom = 1;
2095 caed8802 bellard
                bdrv_set_change_cb(s->bs, cdrom_change_cb, s);
2096 5391d806 bellard
            }
2097 5391d806 bellard
        }
2098 aedf5382 bellard
        s->drive_serial = drive_serial++;
2099 5457c8ce bellard
        s->set_irq = set_irq;
2100 5457c8ce bellard
        s->irq_opaque = irq_opaque;
2101 caed8802 bellard
        s->irq = irq;
2102 a09db21f bellard
        s->sector_write_timer = qemu_new_timer(vm_clock, 
2103 a09db21f bellard
                                               ide_sector_write_timer_cb, s);
2104 5391d806 bellard
        ide_reset(s);
2105 5391d806 bellard
    }
2106 69b91039 bellard
}
2107 69b91039 bellard
2108 34e538ae bellard
static void ide_init_ioport(IDEState *ide_state, int iobase, int iobase2)
2109 69b91039 bellard
{
2110 caed8802 bellard
    register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state);
2111 caed8802 bellard
    register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state);
2112 caed8802 bellard
    if (iobase2) {
2113 caed8802 bellard
        register_ioport_read(iobase2, 1, 1, ide_status_read, ide_state);
2114 caed8802 bellard
        register_ioport_write(iobase2, 1, 1, ide_cmd_write, ide_state);
2115 5391d806 bellard
    }
2116 caed8802 bellard
    
2117 caed8802 bellard
    /* data ports */
2118 caed8802 bellard
    register_ioport_write(iobase, 2, 2, ide_data_writew, ide_state);
2119 caed8802 bellard
    register_ioport_read(iobase, 2, 2, ide_data_readw, ide_state);
2120 caed8802 bellard
    register_ioport_write(iobase, 4, 4, ide_data_writel, ide_state);
2121 caed8802 bellard
    register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state);
2122 5391d806 bellard
}
2123 69b91039 bellard
2124 69b91039 bellard
/***********************************************************/
2125 34e538ae bellard
/* ISA IDE definitions */
2126 34e538ae bellard
2127 34e538ae bellard
void isa_ide_init(int iobase, int iobase2, int irq,
2128 34e538ae bellard
                  BlockDriverState *hd0, BlockDriverState *hd1)
2129 34e538ae bellard
{
2130 34e538ae bellard
    IDEState *ide_state;
2131 34e538ae bellard
2132 34e538ae bellard
    ide_state = qemu_mallocz(sizeof(IDEState) * 2);
2133 34e538ae bellard
    if (!ide_state)
2134 34e538ae bellard
        return;
2135 34e538ae bellard
    
2136 3de388f6 bellard
    ide_init2(ide_state, hd0, hd1, pic_set_irq_new, isa_pic, irq);
2137 34e538ae bellard
    ide_init_ioport(ide_state, iobase, iobase2);
2138 34e538ae bellard
}
2139 34e538ae bellard
2140 34e538ae bellard
/***********************************************************/
2141 69b91039 bellard
/* PCI IDE definitions */
2142 69b91039 bellard
2143 5457c8ce bellard
static void cmd646_update_irq(PCIIDEState *d);
2144 5457c8ce bellard
2145 69b91039 bellard
static void ide_map(PCIDevice *pci_dev, int region_num, 
2146 69b91039 bellard
                    uint32_t addr, uint32_t size, int type)
2147 69b91039 bellard
{
2148 69b91039 bellard
    PCIIDEState *d = (PCIIDEState *)pci_dev;
2149 69b91039 bellard
    IDEState *ide_state;
2150 69b91039 bellard
2151 69b91039 bellard
    if (region_num <= 3) {
2152 69b91039 bellard
        ide_state = &d->ide_if[(region_num >> 1) * 2];
2153 69b91039 bellard
        if (region_num & 1) {
2154 69b91039 bellard
            register_ioport_read(addr + 2, 1, 1, ide_status_read, ide_state);
2155 69b91039 bellard
            register_ioport_write(addr + 2, 1, 1, ide_cmd_write, ide_state);
2156 69b91039 bellard
        } else {
2157 69b91039 bellard
            register_ioport_write(addr, 8, 1, ide_ioport_write, ide_state);
2158 69b91039 bellard
            register_ioport_read(addr, 8, 1, ide_ioport_read, ide_state);
2159 69b91039 bellard
2160 69b91039 bellard
            /* data ports */
2161 69b91039 bellard
            register_ioport_write(addr, 2, 2, ide_data_writew, ide_state);
2162 69b91039 bellard
            register_ioport_read(addr, 2, 2, ide_data_readw, ide_state);
2163 69b91039 bellard
            register_ioport_write(addr, 4, 4, ide_data_writel, ide_state);
2164 69b91039 bellard
            register_ioport_read(addr, 4, 4, ide_data_readl, ide_state);
2165 69b91039 bellard
        }
2166 69b91039 bellard
    }
2167 69b91039 bellard
}
2168 69b91039 bellard
2169 8ccad811 bellard
static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb)
2170 98087450 bellard
{
2171 98087450 bellard
    BMDMAState *bm = s->bmdma;
2172 98087450 bellard
    if(!bm)
2173 98087450 bellard
        return;
2174 98087450 bellard
    bm->ide_if = s;
2175 98087450 bellard
    bm->dma_cb = dma_cb;
2176 8ccad811 bellard
    bm->cur_addr = bm->addr;
2177 8ccad811 bellard
    bm->cur_prd_last = 0;
2178 8ccad811 bellard
    bm->cur_prd_addr = 0;
2179 8ccad811 bellard
    bm->cur_prd_len = 0;
2180 98087450 bellard
    if (bm->status & BM_STATUS_DMAING) {
2181 8ccad811 bellard
        bm->dma_cb(bm, 0);
2182 98087450 bellard
    }
2183 98087450 bellard
}
2184 98087450 bellard
2185 98087450 bellard
static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
2186 98087450 bellard
{
2187 98087450 bellard
    BMDMAState *bm = opaque;
2188 98087450 bellard
#ifdef DEBUG_IDE
2189 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2190 98087450 bellard
#endif
2191 98087450 bellard
    if (!(val & BM_CMD_START)) {
2192 98087450 bellard
        /* XXX: do it better */
2193 8ccad811 bellard
        if (bm->status & BM_STATUS_DMAING) {
2194 8ccad811 bellard
            bm->status &= ~BM_STATUS_DMAING;
2195 8ccad811 bellard
            /* cancel DMA request */
2196 8ccad811 bellard
            bm->ide_if = NULL;
2197 8ccad811 bellard
            bm->dma_cb = NULL;
2198 8ccad811 bellard
            if (bm->aiocb) {
2199 8ccad811 bellard
#ifdef DEBUG_AIO
2200 8ccad811 bellard
                printf("aio_cancel\n");
2201 8ccad811 bellard
#endif
2202 8ccad811 bellard
                bdrv_aio_cancel(bm->aiocb);
2203 8ccad811 bellard
                bm->aiocb = NULL;
2204 8ccad811 bellard
            }
2205 8ccad811 bellard
        }
2206 98087450 bellard
        bm->cmd = val & 0x09;
2207 98087450 bellard
    } else {
2208 8ccad811 bellard
        if (!(bm->status & BM_STATUS_DMAING)) {
2209 8ccad811 bellard
            bm->status |= BM_STATUS_DMAING;
2210 8ccad811 bellard
            /* start dma transfer if possible */
2211 8ccad811 bellard
            if (bm->dma_cb)
2212 8ccad811 bellard
                bm->dma_cb(bm, 0);
2213 8ccad811 bellard
        }
2214 98087450 bellard
        bm->cmd = val & 0x09;
2215 98087450 bellard
    }
2216 98087450 bellard
}
2217 98087450 bellard
2218 5457c8ce bellard
static uint32_t bmdma_readb(void *opaque, uint32_t addr)
2219 98087450 bellard
{
2220 98087450 bellard
    BMDMAState *bm = opaque;
2221 5457c8ce bellard
    PCIIDEState *pci_dev;
2222 98087450 bellard
    uint32_t val;
2223 5457c8ce bellard
    
2224 5457c8ce bellard
    switch(addr & 3) {
2225 5457c8ce bellard
    case 0: 
2226 5457c8ce bellard
        val = bm->cmd;
2227 5457c8ce bellard
        break;
2228 5457c8ce bellard
    case 1:
2229 5457c8ce bellard
        pci_dev = bm->pci_dev;
2230 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2231 5457c8ce bellard
            val = pci_dev->dev.config[MRDMODE];
2232 5457c8ce bellard
        } else {
2233 5457c8ce bellard
            val = 0xff;
2234 5457c8ce bellard
        }
2235 5457c8ce bellard
        break;
2236 5457c8ce bellard
    case 2:
2237 5457c8ce bellard
        val = bm->status;
2238 5457c8ce bellard
        break;
2239 5457c8ce bellard
    case 3:
2240 5457c8ce bellard
        pci_dev = bm->pci_dev;
2241 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2242 5457c8ce bellard
            if (bm == &pci_dev->bmdma[0])
2243 5457c8ce bellard
                val = pci_dev->dev.config[UDIDETCR0];
2244 5457c8ce bellard
            else
2245 5457c8ce bellard
                val = pci_dev->dev.config[UDIDETCR1];
2246 5457c8ce bellard
        } else {
2247 5457c8ce bellard
            val = 0xff;
2248 5457c8ce bellard
        }
2249 5457c8ce bellard
        break;
2250 5457c8ce bellard
    default:
2251 5457c8ce bellard
        val = 0xff;
2252 5457c8ce bellard
        break;
2253 5457c8ce bellard
    }
2254 98087450 bellard
#ifdef DEBUG_IDE
2255 5457c8ce bellard
    printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
2256 98087450 bellard
#endif
2257 98087450 bellard
    return val;
2258 98087450 bellard
}
2259 98087450 bellard
2260 5457c8ce bellard
static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
2261 98087450 bellard
{
2262 98087450 bellard
    BMDMAState *bm = opaque;
2263 5457c8ce bellard
    PCIIDEState *pci_dev;
2264 98087450 bellard
#ifdef DEBUG_IDE
2265 5457c8ce bellard
    printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
2266 98087450 bellard
#endif
2267 5457c8ce bellard
    switch(addr & 3) {
2268 5457c8ce bellard
    case 1:
2269 5457c8ce bellard
        pci_dev = bm->pci_dev;
2270 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2271 5457c8ce bellard
            pci_dev->dev.config[MRDMODE] = 
2272 5457c8ce bellard
                (pci_dev->dev.config[MRDMODE] & ~0x30) | (val & 0x30);
2273 5457c8ce bellard
            cmd646_update_irq(pci_dev);
2274 5457c8ce bellard
        }
2275 5457c8ce bellard
        break;
2276 5457c8ce bellard
    case 2:
2277 5457c8ce bellard
        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
2278 5457c8ce bellard
        break;
2279 5457c8ce bellard
    case 3:
2280 5457c8ce bellard
        pci_dev = bm->pci_dev;
2281 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2282 5457c8ce bellard
            if (bm == &pci_dev->bmdma[0])
2283 5457c8ce bellard
                pci_dev->dev.config[UDIDETCR0] = val;
2284 5457c8ce bellard
            else
2285 5457c8ce bellard
                pci_dev->dev.config[UDIDETCR1] = val;
2286 5457c8ce bellard
        }
2287 5457c8ce bellard
        break;
2288 5457c8ce bellard
    }
2289 98087450 bellard
}
2290 98087450 bellard
2291 98087450 bellard
static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr)
2292 98087450 bellard
{
2293 98087450 bellard
    BMDMAState *bm = opaque;
2294 98087450 bellard
    uint32_t val;
2295 98087450 bellard
    val = bm->addr;
2296 98087450 bellard
#ifdef DEBUG_IDE
2297 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2298 98087450 bellard
#endif
2299 98087450 bellard
    return val;
2300 98087450 bellard
}
2301 98087450 bellard
2302 98087450 bellard
static void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val)
2303 98087450 bellard
{
2304 98087450 bellard
    BMDMAState *bm = opaque;
2305 98087450 bellard
#ifdef DEBUG_IDE
2306 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2307 98087450 bellard
#endif
2308 98087450 bellard
    bm->addr = val & ~3;
2309 98087450 bellard
}
2310 98087450 bellard
2311 98087450 bellard
static void bmdma_map(PCIDevice *pci_dev, int region_num, 
2312 98087450 bellard
                    uint32_t addr, uint32_t size, int type)
2313 98087450 bellard
{
2314 98087450 bellard
    PCIIDEState *d = (PCIIDEState *)pci_dev;
2315 98087450 bellard
    int i;
2316 98087450 bellard
2317 98087450 bellard
    for(i = 0;i < 2; i++) {
2318 98087450 bellard
        BMDMAState *bm = &d->bmdma[i];
2319 98087450 bellard
        d->ide_if[2 * i].bmdma = bm;
2320 98087450 bellard
        d->ide_if[2 * i + 1].bmdma = bm;
2321 5457c8ce bellard
        bm->pci_dev = (PCIIDEState *)pci_dev;
2322 5457c8ce bellard
2323 98087450 bellard
        register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
2324 98087450 bellard
2325 5457c8ce bellard
        register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
2326 5457c8ce bellard
        register_ioport_read(addr, 4, 1, bmdma_readb, bm);
2327 98087450 bellard
2328 98087450 bellard
        register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm);
2329 98087450 bellard
        register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm);
2330 98087450 bellard
        addr += 8;
2331 98087450 bellard
    }
2332 98087450 bellard
}
2333 98087450 bellard
2334 5457c8ce bellard
/* XXX: call it also when the MRDMODE is changed from the PCI config
2335 5457c8ce bellard
   registers */
2336 5457c8ce bellard
static void cmd646_update_irq(PCIIDEState *d)
2337 5457c8ce bellard
{
2338 5457c8ce bellard
    int pci_level;
2339 5457c8ce bellard
    pci_level = ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH0) &&
2340 5457c8ce bellard
                 !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH0)) ||
2341 5457c8ce bellard
        ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH1) &&
2342 5457c8ce bellard
         !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH1));
2343 5457c8ce bellard
    pci_set_irq((PCIDevice *)d, 0, pci_level);
2344 5457c8ce bellard
}
2345 5457c8ce bellard
2346 5457c8ce bellard
/* the PCI irq level is the logical OR of the two channels */
2347 5457c8ce bellard
static void cmd646_set_irq(void *opaque, int channel, int level)
2348 5457c8ce bellard
{
2349 5457c8ce bellard
    PCIIDEState *d = opaque;
2350 5457c8ce bellard
    int irq_mask;
2351 5457c8ce bellard
2352 5457c8ce bellard
    irq_mask = MRDMODE_INTR_CH0 << channel;
2353 5457c8ce bellard
    if (level)
2354 5457c8ce bellard
        d->dev.config[MRDMODE] |= irq_mask;
2355 5457c8ce bellard
    else
2356 5457c8ce bellard
        d->dev.config[MRDMODE] &= ~irq_mask;
2357 5457c8ce bellard
    cmd646_update_irq(d);
2358 5457c8ce bellard
}
2359 5457c8ce bellard
2360 5457c8ce bellard
/* CMD646 PCI IDE controller */
2361 5457c8ce bellard
void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
2362 5457c8ce bellard
                         int secondary_ide_enabled)
2363 69b91039 bellard
{
2364 69b91039 bellard
    PCIIDEState *d;
2365 69b91039 bellard
    uint8_t *pci_conf;
2366 34e538ae bellard
    int i;
2367 34e538ae bellard
2368 5457c8ce bellard
    d = (PCIIDEState *)pci_register_device(bus, "CMD646 IDE", 
2369 5457c8ce bellard
                                           sizeof(PCIIDEState),
2370 46e50e9d bellard
                                           -1, 
2371 73c11f63 bellard
                                           NULL, NULL);
2372 5457c8ce bellard
    d->type = IDE_TYPE_CMD646;
2373 69b91039 bellard
    pci_conf = d->dev.config;
2374 5457c8ce bellard
    pci_conf[0x00] = 0x95; // CMD646
2375 5457c8ce bellard
    pci_conf[0x01] = 0x10;
2376 5457c8ce bellard
    pci_conf[0x02] = 0x46;
2377 5457c8ce bellard
    pci_conf[0x03] = 0x06;
2378 5457c8ce bellard
2379 5457c8ce bellard
    pci_conf[0x08] = 0x07; // IDE controller revision
2380 5457c8ce bellard
    pci_conf[0x09] = 0x8f; 
2381 5457c8ce bellard
2382 69b91039 bellard
    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
2383 69b91039 bellard
    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
2384 5457c8ce bellard
    pci_conf[0x0e] = 0x00; // header_type
2385 5457c8ce bellard
    
2386 5457c8ce bellard
    if (secondary_ide_enabled) {
2387 5457c8ce bellard
        /* XXX: if not enabled, really disable the seconday IDE controller */
2388 5457c8ce bellard
        pci_conf[0x51] = 0x80; /* enable IDE1 */
2389 5457c8ce bellard
    }
2390 69b91039 bellard
2391 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 0, 0x8, 
2392 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2393 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 1, 0x4, 
2394 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2395 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 2, 0x8, 
2396 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2397 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 3, 0x4, 
2398 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2399 98087450 bellard
    pci_register_io_region((PCIDevice *)d, 4, 0x10, 
2400 98087450 bellard
                           PCI_ADDRESS_SPACE_IO, bmdma_map);
2401 69b91039 bellard
2402 34e538ae bellard
    pci_conf[0x3d] = 0x01; // interrupt on pin 1
2403 5457c8ce bellard
    
2404 34e538ae bellard
    for(i = 0; i < 4; i++)
2405 34e538ae bellard
        d->ide_if[i].pci_dev = (PCIDevice *)d;
2406 5457c8ce bellard
    ide_init2(&d->ide_if[0], hd_table[0], hd_table[1],
2407 5457c8ce bellard
              cmd646_set_irq, d, 0);
2408 5457c8ce bellard
    ide_init2(&d->ide_if[2], hd_table[2], hd_table[3],
2409 5457c8ce bellard
              cmd646_set_irq, d, 1);
2410 34e538ae bellard
}
2411 34e538ae bellard
2412 c3d78997 bellard
static void pci_ide_save(QEMUFile* f, void *opaque)
2413 c3d78997 bellard
{
2414 c3d78997 bellard
    PCIIDEState *d = opaque;
2415 c3d78997 bellard
    int i;
2416 c3d78997 bellard
2417 c3d78997 bellard
    pci_device_save(&d->dev, f);
2418 c3d78997 bellard
2419 c3d78997 bellard
    for(i = 0; i < 2; i++) {
2420 c3d78997 bellard
        BMDMAState *bm = &d->bmdma[i];
2421 c3d78997 bellard
        qemu_put_8s(f, &bm->cmd);
2422 c3d78997 bellard
        qemu_put_8s(f, &bm->status);
2423 c3d78997 bellard
        qemu_put_be32s(f, &bm->addr);
2424 c3d78997 bellard
        /* XXX: if a transfer is pending, we do not save it yet */
2425 c3d78997 bellard
    }
2426 c3d78997 bellard
2427 c3d78997 bellard
    /* per IDE interface data */
2428 c3d78997 bellard
    for(i = 0; i < 2; i++) {
2429 c3d78997 bellard
        IDEState *s = &d->ide_if[i * 2];
2430 c3d78997 bellard
        uint8_t drive1_selected;
2431 c3d78997 bellard
        qemu_put_8s(f, &s->cmd);
2432 c3d78997 bellard
        drive1_selected = (s->cur_drive != s);
2433 c3d78997 bellard
        qemu_put_8s(f, &drive1_selected);
2434 c3d78997 bellard
    }
2435 c3d78997 bellard
2436 c3d78997 bellard
    /* per IDE drive data */
2437 c3d78997 bellard
    for(i = 0; i < 4; i++) {
2438 c3d78997 bellard
        IDEState *s = &d->ide_if[i];
2439 c3d78997 bellard
        qemu_put_be32s(f, &s->mult_sectors);
2440 c3d78997 bellard
        qemu_put_be32s(f, &s->identify_set);
2441 c3d78997 bellard
        if (s->identify_set) {
2442 c3d78997 bellard
            qemu_put_buffer(f, (const uint8_t *)s->identify_data, 512);
2443 c3d78997 bellard
        }
2444 c3d78997 bellard
        qemu_put_8s(f, &s->feature);
2445 c3d78997 bellard
        qemu_put_8s(f, &s->error);
2446 c3d78997 bellard
        qemu_put_be32s(f, &s->nsector);
2447 c3d78997 bellard
        qemu_put_8s(f, &s->sector);
2448 c3d78997 bellard
        qemu_put_8s(f, &s->lcyl);
2449 c3d78997 bellard
        qemu_put_8s(f, &s->hcyl);
2450 c3d78997 bellard
        qemu_put_8s(f, &s->hob_feature);
2451 c3d78997 bellard
        qemu_put_8s(f, &s->hob_nsector);
2452 c3d78997 bellard
        qemu_put_8s(f, &s->hob_sector);
2453 c3d78997 bellard
        qemu_put_8s(f, &s->hob_lcyl);
2454 c3d78997 bellard
        qemu_put_8s(f, &s->hob_hcyl);
2455 c3d78997 bellard
        qemu_put_8s(f, &s->select);
2456 c3d78997 bellard
        qemu_put_8s(f, &s->status);
2457 c3d78997 bellard
        qemu_put_8s(f, &s->lba48);
2458 c3d78997 bellard
2459 c3d78997 bellard
        qemu_put_8s(f, &s->sense_key);
2460 c3d78997 bellard
        qemu_put_8s(f, &s->asc);
2461 c3d78997 bellard
        /* XXX: if a transfer is pending, we do not save it yet */
2462 c3d78997 bellard
    }
2463 c3d78997 bellard
}
2464 c3d78997 bellard
2465 c3d78997 bellard
static int pci_ide_load(QEMUFile* f, void *opaque, int version_id)
2466 c3d78997 bellard
{
2467 c3d78997 bellard
    PCIIDEState *d = opaque;
2468 c3d78997 bellard
    int ret, i;
2469 c3d78997 bellard
2470 c3d78997 bellard
    if (version_id != 1)
2471 c3d78997 bellard
        return -EINVAL;
2472 c3d78997 bellard
    ret = pci_device_load(&d->dev, f);
2473 c3d78997 bellard
    if (ret < 0)
2474 c3d78997 bellard
        return ret;
2475 c3d78997 bellard
2476 c3d78997 bellard
    for(i = 0; i < 2; i++) {
2477 c3d78997 bellard
        BMDMAState *bm = &d->bmdma[i];
2478 c3d78997 bellard
        qemu_get_8s(f, &bm->cmd);
2479 c3d78997 bellard
        qemu_get_8s(f, &bm->status);
2480 c3d78997 bellard
        qemu_get_be32s(f, &bm->addr);
2481 c3d78997 bellard
        /* XXX: if a transfer is pending, we do not save it yet */
2482 c3d78997 bellard
    }
2483 c3d78997 bellard
2484 c3d78997 bellard
    /* per IDE interface data */
2485 c3d78997 bellard
    for(i = 0; i < 2; i++) {
2486 c3d78997 bellard
        IDEState *s = &d->ide_if[i * 2];
2487 c3d78997 bellard
        uint8_t drive1_selected;
2488 c3d78997 bellard
        qemu_get_8s(f, &s->cmd);
2489 c3d78997 bellard
        qemu_get_8s(f, &drive1_selected);
2490 c3d78997 bellard
        s->cur_drive = &d->ide_if[i * 2 + (drive1_selected != 0)];
2491 c3d78997 bellard
    }
2492 c3d78997 bellard
2493 c3d78997 bellard
    /* per IDE drive data */
2494 c3d78997 bellard
    for(i = 0; i < 4; i++) {
2495 c3d78997 bellard
        IDEState *s = &d->ide_if[i];
2496 c3d78997 bellard
        qemu_get_be32s(f, &s->mult_sectors);
2497 c3d78997 bellard
        qemu_get_be32s(f, &s->identify_set);
2498 c3d78997 bellard
        if (s->identify_set) {
2499 c3d78997 bellard
            qemu_get_buffer(f, (uint8_t *)s->identify_data, 512);
2500 c3d78997 bellard
        }
2501 c3d78997 bellard
        qemu_get_8s(f, &s->feature);
2502 c3d78997 bellard
        qemu_get_8s(f, &s->error);
2503 c3d78997 bellard
        qemu_get_be32s(f, &s->nsector);
2504 c3d78997 bellard
        qemu_get_8s(f, &s->sector);
2505 c3d78997 bellard
        qemu_get_8s(f, &s->lcyl);
2506 c3d78997 bellard
        qemu_get_8s(f, &s->hcyl);
2507 c3d78997 bellard
        qemu_get_8s(f, &s->hob_feature);
2508 c3d78997 bellard
        qemu_get_8s(f, &s->hob_nsector);
2509 c3d78997 bellard
        qemu_get_8s(f, &s->hob_sector);
2510 c3d78997 bellard
        qemu_get_8s(f, &s->hob_lcyl);
2511 c3d78997 bellard
        qemu_get_8s(f, &s->hob_hcyl);
2512 c3d78997 bellard
        qemu_get_8s(f, &s->select);
2513 c3d78997 bellard
        qemu_get_8s(f, &s->status);
2514 c3d78997 bellard
        qemu_get_8s(f, &s->lba48);
2515 c3d78997 bellard
2516 c3d78997 bellard
        qemu_get_8s(f, &s->sense_key);
2517 c3d78997 bellard
        qemu_get_8s(f, &s->asc);
2518 c3d78997 bellard
        /* XXX: if a transfer is pending, we do not save it yet */
2519 c3d78997 bellard
    }
2520 c3d78997 bellard
    return 0;
2521 c3d78997 bellard
}
2522 c3d78997 bellard
2523 34e538ae bellard
/* hd_table must contain 4 block drivers */
2524 34e538ae bellard
/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
2525 502a5395 pbrook
void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn)
2526 34e538ae bellard
{
2527 34e538ae bellard
    PCIIDEState *d;
2528 34e538ae bellard
    uint8_t *pci_conf;
2529 34e538ae bellard
    
2530 34e538ae bellard
    /* register a function 1 of PIIX3 */
2531 46e50e9d bellard
    d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE", 
2532 46e50e9d bellard
                                           sizeof(PCIIDEState),
2533 502a5395 pbrook
                                           devfn,
2534 34e538ae bellard
                                           NULL, NULL);
2535 5457c8ce bellard
    d->type = IDE_TYPE_PIIX3;
2536 5457c8ce bellard
2537 34e538ae bellard
    pci_conf = d->dev.config;
2538 34e538ae bellard
    pci_conf[0x00] = 0x86; // Intel
2539 34e538ae bellard
    pci_conf[0x01] = 0x80;
2540 34e538ae bellard
    pci_conf[0x02] = 0x10;
2541 34e538ae bellard
    pci_conf[0x03] = 0x70;
2542 92510b8c bellard
    pci_conf[0x09] = 0x80; // legacy ATA mode
2543 34e538ae bellard
    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
2544 34e538ae bellard
    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
2545 34e538ae bellard
    pci_conf[0x0e] = 0x00; // header_type
2546 34e538ae bellard
2547 98087450 bellard
    pci_register_io_region((PCIDevice *)d, 4, 0x10, 
2548 98087450 bellard
                           PCI_ADDRESS_SPACE_IO, bmdma_map);
2549 34e538ae bellard
2550 5457c8ce bellard
    ide_init2(&d->ide_if[0], hd_table[0], hd_table[1],
2551 3de388f6 bellard
              pic_set_irq_new, isa_pic, 14);
2552 5457c8ce bellard
    ide_init2(&d->ide_if[2], hd_table[2], hd_table[3],
2553 3de388f6 bellard
              pic_set_irq_new, isa_pic, 15);
2554 34e538ae bellard
    ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
2555 34e538ae bellard
    ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
2556 c3d78997 bellard
2557 c3d78997 bellard
    register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
2558 69b91039 bellard
}
2559 1ade1de2 bellard
2560 1ade1de2 bellard
/***********************************************************/
2561 1ade1de2 bellard
/* MacIO based PowerPC IDE */
2562 1ade1de2 bellard
2563 1ade1de2 bellard
/* PowerMac IDE memory IO */
2564 1ade1de2 bellard
static void pmac_ide_writeb (void *opaque,
2565 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
2566 1ade1de2 bellard
{
2567 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2568 1ade1de2 bellard
    switch (addr) {
2569 1ade1de2 bellard
    case 1 ... 7:
2570 1ade1de2 bellard
        ide_ioport_write(opaque, addr, val);
2571 1ade1de2 bellard
        break;
2572 1ade1de2 bellard
    case 8:
2573 1ade1de2 bellard
    case 22:
2574 1ade1de2 bellard
        ide_cmd_write(opaque, 0, val);
2575 1ade1de2 bellard
        break;
2576 1ade1de2 bellard
    default:
2577 1ade1de2 bellard
        break;
2578 1ade1de2 bellard
    }
2579 1ade1de2 bellard
}
2580 1ade1de2 bellard
2581 1ade1de2 bellard
static uint32_t pmac_ide_readb (void *opaque,target_phys_addr_t addr)
2582 1ade1de2 bellard
{
2583 1ade1de2 bellard
    uint8_t retval;
2584 1ade1de2 bellard
2585 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4;
2586 1ade1de2 bellard
    switch (addr) {
2587 1ade1de2 bellard
    case 1 ... 7:
2588 1ade1de2 bellard
        retval = ide_ioport_read(opaque, addr);
2589 1ade1de2 bellard
        break;
2590 1ade1de2 bellard
    case 8:
2591 1ade1de2 bellard
    case 22:
2592 1ade1de2 bellard
        retval = ide_status_read(opaque, 0);
2593 1ade1de2 bellard
        break;
2594 1ade1de2 bellard
    default:
2595 1ade1de2 bellard
        retval = 0xFF;
2596 1ade1de2 bellard
        break;
2597 1ade1de2 bellard
    }
2598 1ade1de2 bellard
    return retval;
2599 1ade1de2 bellard
}
2600 1ade1de2 bellard
2601 1ade1de2 bellard
static void pmac_ide_writew (void *opaque,
2602 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
2603 1ade1de2 bellard
{
2604 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2605 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2606 1ade1de2 bellard
    val = bswap16(val);
2607 1ade1de2 bellard
#endif
2608 1ade1de2 bellard
    if (addr == 0) {
2609 1ade1de2 bellard
        ide_data_writew(opaque, 0, val);
2610 1ade1de2 bellard
    }
2611 1ade1de2 bellard
}
2612 1ade1de2 bellard
2613 1ade1de2 bellard
static uint32_t pmac_ide_readw (void *opaque,target_phys_addr_t addr)
2614 1ade1de2 bellard
{
2615 1ade1de2 bellard
    uint16_t retval;
2616 1ade1de2 bellard
2617 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2618 1ade1de2 bellard
    if (addr == 0) {
2619 1ade1de2 bellard
        retval = ide_data_readw(opaque, 0);
2620 1ade1de2 bellard
    } else {
2621 1ade1de2 bellard
        retval = 0xFFFF;
2622 1ade1de2 bellard
    }
2623 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2624 1ade1de2 bellard
    retval = bswap16(retval);
2625 1ade1de2 bellard
#endif
2626 1ade1de2 bellard
    return retval;
2627 1ade1de2 bellard
}
2628 1ade1de2 bellard
2629 1ade1de2 bellard
static void pmac_ide_writel (void *opaque,
2630 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
2631 1ade1de2 bellard
{
2632 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2633 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2634 1ade1de2 bellard
    val = bswap32(val);
2635 1ade1de2 bellard
#endif
2636 1ade1de2 bellard
    if (addr == 0) {
2637 1ade1de2 bellard
        ide_data_writel(opaque, 0, val);
2638 1ade1de2 bellard
    }
2639 1ade1de2 bellard
}
2640 1ade1de2 bellard
2641 1ade1de2 bellard
static uint32_t pmac_ide_readl (void *opaque,target_phys_addr_t addr)
2642 1ade1de2 bellard
{
2643 1ade1de2 bellard
    uint32_t retval;
2644 1ade1de2 bellard
2645 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2646 1ade1de2 bellard
    if (addr == 0) {
2647 1ade1de2 bellard
        retval = ide_data_readl(opaque, 0);
2648 1ade1de2 bellard
    } else {
2649 1ade1de2 bellard
        retval = 0xFFFFFFFF;
2650 1ade1de2 bellard
    }
2651 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2652 1ade1de2 bellard
    retval = bswap32(retval);
2653 1ade1de2 bellard
#endif
2654 1ade1de2 bellard
    return retval;
2655 1ade1de2 bellard
}
2656 1ade1de2 bellard
2657 1ade1de2 bellard
static CPUWriteMemoryFunc *pmac_ide_write[] = {
2658 1ade1de2 bellard
    pmac_ide_writeb,
2659 1ade1de2 bellard
    pmac_ide_writew,
2660 1ade1de2 bellard
    pmac_ide_writel,
2661 1ade1de2 bellard
};
2662 1ade1de2 bellard
2663 1ade1de2 bellard
static CPUReadMemoryFunc *pmac_ide_read[] = {
2664 1ade1de2 bellard
    pmac_ide_readb,
2665 1ade1de2 bellard
    pmac_ide_readw,
2666 1ade1de2 bellard
    pmac_ide_readl,
2667 1ade1de2 bellard
};
2668 1ade1de2 bellard
2669 1ade1de2 bellard
/* hd_table must contain 4 block drivers */
2670 1ade1de2 bellard
/* PowerMac uses memory mapped registers, not I/O. Return the memory
2671 1ade1de2 bellard
   I/O index to access the ide. */
2672 1ade1de2 bellard
int pmac_ide_init (BlockDriverState **hd_table,
2673 5457c8ce bellard
                   SetIRQFunc *set_irq, void *irq_opaque, int irq)
2674 1ade1de2 bellard
{
2675 1ade1de2 bellard
    IDEState *ide_if;
2676 1ade1de2 bellard
    int pmac_ide_memory;
2677 1ade1de2 bellard
2678 1ade1de2 bellard
    ide_if = qemu_mallocz(sizeof(IDEState) * 2);
2679 5457c8ce bellard
    ide_init2(&ide_if[0], hd_table[0], hd_table[1],
2680 5457c8ce bellard
              set_irq, irq_opaque, irq);
2681 1ade1de2 bellard
    
2682 1ade1de2 bellard
    pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
2683 1ade1de2 bellard
                                             pmac_ide_write, &ide_if[0]);
2684 1ade1de2 bellard
    return pmac_ide_memory;
2685 1ade1de2 bellard
}