Statistics
| Branch: | Revision:

root / hw / ide.c @ 298e01b6

History | View | Annotate | Download (115.1 kB)

1 5391d806 bellard
/*
2 38cdea7c balrog
 * QEMU IDE disk and CD/DVD-ROM Emulator
3 5fafdf24 ths
 *
4 5391d806 bellard
 * Copyright (c) 2003 Fabrice Bellard
5 201a51fc balrog
 * Copyright (c) 2006 Openedhand Ltd.
6 5fafdf24 ths
 *
7 5391d806 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 5391d806 bellard
 * of this software and associated documentation files (the "Software"), to deal
9 5391d806 bellard
 * in the Software without restriction, including without limitation the rights
10 5391d806 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 5391d806 bellard
 * copies of the Software, and to permit persons to whom the Software is
12 5391d806 bellard
 * furnished to do so, subject to the following conditions:
13 5391d806 bellard
 *
14 5391d806 bellard
 * The above copyright notice and this permission notice shall be included in
15 5391d806 bellard
 * all copies or substantial portions of the Software.
16 5391d806 bellard
 *
17 5391d806 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 5391d806 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 5391d806 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 5391d806 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 5391d806 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 5391d806 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 5391d806 bellard
 * THE SOFTWARE.
24 5391d806 bellard
 */
25 87ecb68b pbrook
#include "hw.h"
26 87ecb68b pbrook
#include "pc.h"
27 87ecb68b pbrook
#include "pci.h"
28 87ecb68b pbrook
#include "scsi-disk.h"
29 87ecb68b pbrook
#include "pcmcia.h"
30 87ecb68b pbrook
#include "block.h"
31 87ecb68b pbrook
#include "qemu-timer.h"
32 87ecb68b pbrook
#include "sysemu.h"
33 9596ebb7 pbrook
#include "ppc_mac.h"
34 5391d806 bellard
35 5391d806 bellard
/* debug IDE devices */
36 5391d806 bellard
//#define DEBUG_IDE
37 5391d806 bellard
//#define DEBUG_IDE_ATAPI
38 8ccad811 bellard
//#define DEBUG_AIO
39 8ccad811 bellard
#define USE_DMA_CDROM
40 5391d806 bellard
41 5391d806 bellard
/* Bits of HD_STATUS */
42 5391d806 bellard
#define ERR_STAT                0x01
43 5391d806 bellard
#define INDEX_STAT                0x02
44 5391d806 bellard
#define ECC_STAT                0x04        /* Corrected error */
45 5391d806 bellard
#define DRQ_STAT                0x08
46 5391d806 bellard
#define SEEK_STAT                0x10
47 5391d806 bellard
#define SRV_STAT                0x10
48 5391d806 bellard
#define WRERR_STAT                0x20
49 5391d806 bellard
#define READY_STAT                0x40
50 5391d806 bellard
#define BUSY_STAT                0x80
51 5391d806 bellard
52 5391d806 bellard
/* Bits for HD_ERROR */
53 5391d806 bellard
#define MARK_ERR                0x01        /* Bad address mark */
54 5391d806 bellard
#define TRK0_ERR                0x02        /* couldn't find track 0 */
55 5391d806 bellard
#define ABRT_ERR                0x04        /* Command aborted */
56 5391d806 bellard
#define MCR_ERR                        0x08        /* media change request */
57 5391d806 bellard
#define ID_ERR                        0x10        /* ID field not found */
58 5391d806 bellard
#define MC_ERR                        0x20        /* media changed */
59 5391d806 bellard
#define ECC_ERR                        0x40        /* Uncorrectable ECC error */
60 5391d806 bellard
#define BBD_ERR                        0x80        /* pre-EIDE meaning:  block marked bad */
61 5391d806 bellard
#define ICRC_ERR                0x80        /* new meaning:  CRC error during transfer */
62 5391d806 bellard
63 5391d806 bellard
/* Bits of HD_NSECTOR */
64 5391d806 bellard
#define CD                        0x01
65 5391d806 bellard
#define IO                        0x02
66 5391d806 bellard
#define REL                        0x04
67 5391d806 bellard
#define TAG_MASK                0xf8
68 5391d806 bellard
69 5391d806 bellard
#define IDE_CMD_RESET           0x04
70 5391d806 bellard
#define IDE_CMD_DISABLE_IRQ     0x02
71 5391d806 bellard
72 5391d806 bellard
/* ATA/ATAPI Commands pre T13 Spec */
73 5391d806 bellard
#define WIN_NOP                                0x00
74 5391d806 bellard
/*
75 5391d806 bellard
 *        0x01->0x02 Reserved
76 5391d806 bellard
 */
77 5391d806 bellard
#define CFA_REQ_EXT_ERROR_CODE                0x03 /* CFA Request Extended Error Code */
78 5391d806 bellard
/*
79 5391d806 bellard
 *        0x04->0x07 Reserved
80 5391d806 bellard
 */
81 5391d806 bellard
#define WIN_SRST                        0x08 /* ATAPI soft reset command */
82 5391d806 bellard
#define WIN_DEVICE_RESET                0x08
83 5391d806 bellard
/*
84 5391d806 bellard
 *        0x09->0x0F Reserved
85 5391d806 bellard
 */
86 5391d806 bellard
#define WIN_RECAL                        0x10
87 5391d806 bellard
#define WIN_RESTORE                        WIN_RECAL
88 5391d806 bellard
/*
89 5391d806 bellard
 *        0x10->0x1F Reserved
90 5391d806 bellard
 */
91 5391d806 bellard
#define WIN_READ                        0x20 /* 28-Bit */
92 5391d806 bellard
#define WIN_READ_ONCE                        0x21 /* 28-Bit without retries */
93 5391d806 bellard
#define WIN_READ_LONG                        0x22 /* 28-Bit */
94 5391d806 bellard
#define WIN_READ_LONG_ONCE                0x23 /* 28-Bit without retries */
95 5391d806 bellard
#define WIN_READ_EXT                        0x24 /* 48-Bit */
96 5391d806 bellard
#define WIN_READDMA_EXT                        0x25 /* 48-Bit */
97 5391d806 bellard
#define WIN_READDMA_QUEUED_EXT                0x26 /* 48-Bit */
98 5391d806 bellard
#define WIN_READ_NATIVE_MAX_EXT                0x27 /* 48-Bit */
99 5391d806 bellard
/*
100 5391d806 bellard
 *        0x28
101 5391d806 bellard
 */
102 5391d806 bellard
#define WIN_MULTREAD_EXT                0x29 /* 48-Bit */
103 5391d806 bellard
/*
104 5391d806 bellard
 *        0x2A->0x2F Reserved
105 5391d806 bellard
 */
106 5391d806 bellard
#define WIN_WRITE                        0x30 /* 28-Bit */
107 5391d806 bellard
#define WIN_WRITE_ONCE                        0x31 /* 28-Bit without retries */
108 5391d806 bellard
#define WIN_WRITE_LONG                        0x32 /* 28-Bit */
109 5391d806 bellard
#define WIN_WRITE_LONG_ONCE                0x33 /* 28-Bit without retries */
110 5391d806 bellard
#define WIN_WRITE_EXT                        0x34 /* 48-Bit */
111 5391d806 bellard
#define WIN_WRITEDMA_EXT                0x35 /* 48-Bit */
112 5391d806 bellard
#define WIN_WRITEDMA_QUEUED_EXT                0x36 /* 48-Bit */
113 5391d806 bellard
#define WIN_SET_MAX_EXT                        0x37 /* 48-Bit */
114 5391d806 bellard
#define CFA_WRITE_SECT_WO_ERASE                0x38 /* CFA Write Sectors without erase */
115 5391d806 bellard
#define WIN_MULTWRITE_EXT                0x39 /* 48-Bit */
116 5391d806 bellard
/*
117 5391d806 bellard
 *        0x3A->0x3B Reserved
118 5391d806 bellard
 */
119 5391d806 bellard
#define WIN_WRITE_VERIFY                0x3C /* 28-Bit */
120 5391d806 bellard
/*
121 5391d806 bellard
 *        0x3D->0x3F Reserved
122 5391d806 bellard
 */
123 5391d806 bellard
#define WIN_VERIFY                        0x40 /* 28-Bit - Read Verify Sectors */
124 5391d806 bellard
#define WIN_VERIFY_ONCE                        0x41 /* 28-Bit - without retries */
125 5391d806 bellard
#define WIN_VERIFY_EXT                        0x42 /* 48-Bit */
126 5391d806 bellard
/*
127 5391d806 bellard
 *        0x43->0x4F Reserved
128 5391d806 bellard
 */
129 5391d806 bellard
#define WIN_FORMAT                        0x50
130 5391d806 bellard
/*
131 5391d806 bellard
 *        0x51->0x5F Reserved
132 5391d806 bellard
 */
133 5391d806 bellard
#define WIN_INIT                        0x60
134 5391d806 bellard
/*
135 5391d806 bellard
 *        0x61->0x5F Reserved
136 5391d806 bellard
 */
137 5391d806 bellard
#define WIN_SEEK                        0x70 /* 0x70-0x7F Reserved */
138 5391d806 bellard
#define CFA_TRANSLATE_SECTOR                0x87 /* CFA Translate Sector */
139 5391d806 bellard
#define WIN_DIAGNOSE                        0x90
140 5391d806 bellard
#define WIN_SPECIFY                        0x91 /* set drive geometry translation */
141 5391d806 bellard
#define WIN_DOWNLOAD_MICROCODE                0x92
142 5391d806 bellard
#define WIN_STANDBYNOW2                        0x94
143 201a51fc balrog
#define CFA_IDLEIMMEDIATE                0x95 /* force drive to become "ready" */
144 5391d806 bellard
#define WIN_STANDBY2                        0x96
145 5391d806 bellard
#define WIN_SETIDLE2                        0x97
146 5391d806 bellard
#define WIN_CHECKPOWERMODE2                0x98
147 5391d806 bellard
#define WIN_SLEEPNOW2                        0x99
148 5391d806 bellard
/*
149 5391d806 bellard
 *        0x9A VENDOR
150 5391d806 bellard
 */
151 5391d806 bellard
#define WIN_PACKETCMD                        0xA0 /* Send a packet command. */
152 5391d806 bellard
#define WIN_PIDENTIFY                        0xA1 /* identify ATAPI device        */
153 5391d806 bellard
#define WIN_QUEUED_SERVICE                0xA2
154 5391d806 bellard
#define WIN_SMART                        0xB0 /* self-monitoring and reporting */
155 201a51fc balrog
#define CFA_ACCESS_METADATA_STORAGE        0xB8
156 201a51fc balrog
#define CFA_ERASE_SECTORS               0xC0 /* microdrives implement as NOP */
157 5391d806 bellard
#define WIN_MULTREAD                        0xC4 /* read sectors using multiple mode*/
158 5391d806 bellard
#define WIN_MULTWRITE                        0xC5 /* write sectors using multiple mode */
159 5391d806 bellard
#define WIN_SETMULT                        0xC6 /* enable/disable multiple mode */
160 5391d806 bellard
#define WIN_READDMA_QUEUED                0xC7 /* read sectors using Queued DMA transfers */
161 5391d806 bellard
#define WIN_READDMA                        0xC8 /* read sectors using DMA transfers */
162 5391d806 bellard
#define WIN_READDMA_ONCE                0xC9 /* 28-Bit - without retries */
163 5391d806 bellard
#define WIN_WRITEDMA                        0xCA /* write sectors using DMA transfers */
164 5391d806 bellard
#define WIN_WRITEDMA_ONCE                0xCB /* 28-Bit - without retries */
165 5391d806 bellard
#define WIN_WRITEDMA_QUEUED                0xCC /* write sectors using Queued DMA transfers */
166 5391d806 bellard
#define CFA_WRITE_MULTI_WO_ERASE        0xCD /* CFA Write multiple without erase */
167 5fafdf24 ths
#define WIN_GETMEDIASTATUS                0xDA
168 5391d806 bellard
#define WIN_ACKMEDIACHANGE                0xDB /* ATA-1, ATA-2 vendor */
169 5391d806 bellard
#define WIN_POSTBOOT                        0xDC
170 5391d806 bellard
#define WIN_PREBOOT                        0xDD
171 5391d806 bellard
#define WIN_DOORLOCK                        0xDE /* lock door on removable drives */
172 5391d806 bellard
#define WIN_DOORUNLOCK                        0xDF /* unlock door on removable drives */
173 5391d806 bellard
#define WIN_STANDBYNOW1                        0xE0
174 5391d806 bellard
#define WIN_IDLEIMMEDIATE                0xE1 /* force drive to become "ready" */
175 5391d806 bellard
#define WIN_STANDBY                     0xE2 /* Set device in Standby Mode */
176 5391d806 bellard
#define WIN_SETIDLE1                        0xE3
177 5391d806 bellard
#define WIN_READ_BUFFER                        0xE4 /* force read only 1 sector */
178 5391d806 bellard
#define WIN_CHECKPOWERMODE1                0xE5
179 5391d806 bellard
#define WIN_SLEEPNOW1                        0xE6
180 5391d806 bellard
#define WIN_FLUSH_CACHE                        0xE7
181 5391d806 bellard
#define WIN_WRITE_BUFFER                0xE8 /* force write only 1 sector */
182 5391d806 bellard
#define WIN_WRITE_SAME                        0xE9 /* read ata-2 to use */
183 5391d806 bellard
        /* SET_FEATURES 0x22 or 0xDD */
184 5391d806 bellard
#define WIN_FLUSH_CACHE_EXT                0xEA /* 48-Bit */
185 5391d806 bellard
#define WIN_IDENTIFY                        0xEC /* ask drive to identify itself        */
186 5391d806 bellard
#define WIN_MEDIAEJECT                        0xED
187 5391d806 bellard
#define WIN_IDENTIFY_DMA                0xEE /* same as WIN_IDENTIFY, but DMA */
188 5391d806 bellard
#define WIN_SETFEATURES                        0xEF /* set special drive features */
189 5391d806 bellard
#define EXABYTE_ENABLE_NEST                0xF0
190 201a51fc balrog
#define IBM_SENSE_CONDITION                0xF0 /* measure disk temperature */
191 5391d806 bellard
#define WIN_SECURITY_SET_PASS                0xF1
192 5391d806 bellard
#define WIN_SECURITY_UNLOCK                0xF2
193 5391d806 bellard
#define WIN_SECURITY_ERASE_PREPARE        0xF3
194 5391d806 bellard
#define WIN_SECURITY_ERASE_UNIT                0xF4
195 5391d806 bellard
#define WIN_SECURITY_FREEZE_LOCK        0xF5
196 201a51fc balrog
#define CFA_WEAR_LEVEL                        0xF5 /* microdrives implement as NOP */
197 5391d806 bellard
#define WIN_SECURITY_DISABLE                0xF6
198 5391d806 bellard
#define WIN_READ_NATIVE_MAX                0xF8 /* return the native maximum address */
199 5391d806 bellard
#define WIN_SET_MAX                        0xF9
200 5391d806 bellard
#define DISABLE_SEAGATE                        0xFB
201 5391d806 bellard
202 5391d806 bellard
/* set to 1 set disable mult support */
203 f66723fa bellard
#define MAX_MULT_SECTORS 16
204 5391d806 bellard
205 5391d806 bellard
/* ATAPI defines */
206 5391d806 bellard
207 5391d806 bellard
#define ATAPI_PACKET_SIZE 12
208 5391d806 bellard
209 5391d806 bellard
/* The generic packet command opcodes for CD/DVD Logical Units,
210 5391d806 bellard
 * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */
211 5391d806 bellard
#define GPCMD_BLANK                            0xa1
212 5391d806 bellard
#define GPCMD_CLOSE_TRACK                    0x5b
213 5391d806 bellard
#define GPCMD_FLUSH_CACHE                    0x35
214 5391d806 bellard
#define GPCMD_FORMAT_UNIT                    0x04
215 5391d806 bellard
#define GPCMD_GET_CONFIGURATION                    0x46
216 5391d806 bellard
#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a
217 5391d806 bellard
#define GPCMD_GET_PERFORMANCE                    0xac
218 5391d806 bellard
#define GPCMD_INQUIRY                            0x12
219 5391d806 bellard
#define GPCMD_LOAD_UNLOAD                    0xa6
220 5391d806 bellard
#define GPCMD_MECHANISM_STATUS                    0xbd
221 5391d806 bellard
#define GPCMD_MODE_SELECT_10                    0x55
222 5391d806 bellard
#define GPCMD_MODE_SENSE_10                    0x5a
223 5391d806 bellard
#define GPCMD_PAUSE_RESUME                    0x4b
224 5391d806 bellard
#define GPCMD_PLAY_AUDIO_10                    0x45
225 5391d806 bellard
#define GPCMD_PLAY_AUDIO_MSF                    0x47
226 5391d806 bellard
#define GPCMD_PLAY_AUDIO_TI                    0x48
227 5391d806 bellard
#define GPCMD_PLAY_CD                            0xbc
228 5391d806 bellard
#define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL  0x1e
229 5391d806 bellard
#define GPCMD_READ_10                            0x28
230 5391d806 bellard
#define GPCMD_READ_12                            0xa8
231 5391d806 bellard
#define GPCMD_READ_CDVD_CAPACITY            0x25
232 5391d806 bellard
#define GPCMD_READ_CD                            0xbe
233 5391d806 bellard
#define GPCMD_READ_CD_MSF                    0xb9
234 5391d806 bellard
#define GPCMD_READ_DISC_INFO                    0x51
235 5391d806 bellard
#define GPCMD_READ_DVD_STRUCTURE            0xad
236 5391d806 bellard
#define GPCMD_READ_FORMAT_CAPACITIES            0x23
237 5391d806 bellard
#define GPCMD_READ_HEADER                    0x44
238 5391d806 bellard
#define GPCMD_READ_TRACK_RZONE_INFO            0x52
239 5391d806 bellard
#define GPCMD_READ_SUBCHANNEL                    0x42
240 5391d806 bellard
#define GPCMD_READ_TOC_PMA_ATIP                    0x43
241 5391d806 bellard
#define GPCMD_REPAIR_RZONE_TRACK            0x58
242 5391d806 bellard
#define GPCMD_REPORT_KEY                    0xa4
243 5391d806 bellard
#define GPCMD_REQUEST_SENSE                    0x03
244 5391d806 bellard
#define GPCMD_RESERVE_RZONE_TRACK            0x53
245 5391d806 bellard
#define GPCMD_SCAN                            0xba
246 5391d806 bellard
#define GPCMD_SEEK                            0x2b
247 5391d806 bellard
#define GPCMD_SEND_DVD_STRUCTURE            0xad
248 5391d806 bellard
#define GPCMD_SEND_EVENT                    0xa2
249 5391d806 bellard
#define GPCMD_SEND_KEY                            0xa3
250 5391d806 bellard
#define GPCMD_SEND_OPC                            0x54
251 5391d806 bellard
#define GPCMD_SET_READ_AHEAD                    0xa7
252 5391d806 bellard
#define GPCMD_SET_STREAMING                    0xb6
253 5391d806 bellard
#define GPCMD_START_STOP_UNIT                    0x1b
254 5391d806 bellard
#define GPCMD_STOP_PLAY_SCAN                    0x4e
255 5391d806 bellard
#define GPCMD_TEST_UNIT_READY                    0x00
256 5391d806 bellard
#define GPCMD_VERIFY_10                            0x2f
257 5391d806 bellard
#define GPCMD_WRITE_10                            0x2a
258 5391d806 bellard
#define GPCMD_WRITE_AND_VERIFY_10            0x2e
259 5fafdf24 ths
/* This is listed as optional in ATAPI 2.6, but is (curiously)
260 5391d806 bellard
 * missing from Mt. Fuji, Table 57.  It _is_ mentioned in Mt. Fuji
261 5391d806 bellard
 * Table 377 as an MMC command for SCSi devices though...  Most ATAPI
262 5391d806 bellard
 * drives support it. */
263 5391d806 bellard
#define GPCMD_SET_SPEED                            0xbb
264 5fafdf24 ths
/* This seems to be a SCSI specific CD-ROM opcode
265 5391d806 bellard
 * to play data at track/index */
266 5391d806 bellard
#define GPCMD_PLAYAUDIO_TI                    0x48
267 5391d806 bellard
/*
268 5391d806 bellard
 * From MS Media Status Notification Support Specification. For
269 5391d806 bellard
 * older drives only.
270 5391d806 bellard
 */
271 5391d806 bellard
#define GPCMD_GET_MEDIA_STATUS                    0xda
272 d14049ea ths
#define GPCMD_MODE_SENSE_6                    0x1a
273 5391d806 bellard
274 5391d806 bellard
/* Mode page codes for mode sense/set */
275 5391d806 bellard
#define GPMODE_R_W_ERROR_PAGE                0x01
276 5391d806 bellard
#define GPMODE_WRITE_PARMS_PAGE                0x05
277 5391d806 bellard
#define GPMODE_AUDIO_CTL_PAGE                0x0e
278 5391d806 bellard
#define GPMODE_POWER_PAGE                0x1a
279 5391d806 bellard
#define GPMODE_FAULT_FAIL_PAGE                0x1c
280 5391d806 bellard
#define GPMODE_TO_PROTECT_PAGE                0x1d
281 5391d806 bellard
#define GPMODE_CAPABILITIES_PAGE        0x2a
282 5391d806 bellard
#define GPMODE_ALL_PAGES                0x3f
283 5391d806 bellard
/* Not in Mt. Fuji, but in ATAPI 2.6 -- depricated now in favor
284 5391d806 bellard
 * of MODE_SENSE_POWER_PAGE */
285 5391d806 bellard
#define GPMODE_CDROM_PAGE                0x0d
286 5391d806 bellard
287 38cdea7c balrog
/*
288 38cdea7c balrog
 * Based on values from <linux/cdrom.h> but extending CD_MINS
289 38cdea7c balrog
 * to the maximum common size allowed by the Orange's Book ATIP
290 38cdea7c balrog
 *
291 38cdea7c balrog
 * 90 and 99 min CDs are also available but using them as the
292 38cdea7c balrog
 * upper limit reduces the effectiveness of the heuristic to
293 38cdea7c balrog
 * detect DVDs burned to less than 25% of their maximum capacity
294 38cdea7c balrog
 */
295 38cdea7c balrog
296 38cdea7c balrog
/* Some generally useful CD-ROM information */
297 38cdea7c balrog
#define CD_MINS                       80 /* max. minutes per CD */
298 38cdea7c balrog
#define CD_SECS                       60 /* seconds per minute */
299 38cdea7c balrog
#define CD_FRAMES                     75 /* frames per second */
300 38cdea7c balrog
#define CD_FRAMESIZE                2048 /* bytes per frame, "cooked" mode */
301 38cdea7c balrog
#define CD_MAX_BYTES       (CD_MINS * CD_SECS * CD_FRAMES * CD_FRAMESIZE)
302 38cdea7c balrog
#define CD_MAX_SECTORS     (CD_MAX_BYTES / 512)
303 38cdea7c balrog
304 38cdea7c balrog
/*
305 38cdea7c balrog
 * The MMC values are not IDE specific and might need to be moved
306 38cdea7c balrog
 * to a common header if they are also needed for the SCSI emulation
307 38cdea7c balrog
 */
308 38cdea7c balrog
309 38cdea7c balrog
/* Profile list from MMC-6 revision 1 table 91 */
310 38cdea7c balrog
#define MMC_PROFILE_NONE                0x0000
311 38cdea7c balrog
#define MMC_PROFILE_CD_ROM              0x0008
312 38cdea7c balrog
#define MMC_PROFILE_CD_R                0x0009
313 38cdea7c balrog
#define MMC_PROFILE_CD_RW               0x000A
314 38cdea7c balrog
#define MMC_PROFILE_DVD_ROM             0x0010
315 38cdea7c balrog
#define MMC_PROFILE_DVD_R_SR            0x0011
316 38cdea7c balrog
#define MMC_PROFILE_DVD_RAM             0x0012
317 38cdea7c balrog
#define MMC_PROFILE_DVD_RW_RO           0x0013
318 38cdea7c balrog
#define MMC_PROFILE_DVD_RW_SR           0x0014
319 38cdea7c balrog
#define MMC_PROFILE_DVD_R_DL_SR         0x0015
320 38cdea7c balrog
#define MMC_PROFILE_DVD_R_DL_JR         0x0016
321 38cdea7c balrog
#define MMC_PROFILE_DVD_RW_DL           0x0017
322 38cdea7c balrog
#define MMC_PROFILE_DVD_DDR             0x0018
323 38cdea7c balrog
#define MMC_PROFILE_DVD_PLUS_RW         0x001A
324 38cdea7c balrog
#define MMC_PROFILE_DVD_PLUS_R          0x001B
325 38cdea7c balrog
#define MMC_PROFILE_DVD_PLUS_RW_DL      0x002A
326 38cdea7c balrog
#define MMC_PROFILE_DVD_PLUS_R_DL       0x002B
327 38cdea7c balrog
#define MMC_PROFILE_BD_ROM              0x0040
328 38cdea7c balrog
#define MMC_PROFILE_BD_R_SRM            0x0041
329 38cdea7c balrog
#define MMC_PROFILE_BD_R_RRM            0x0042
330 38cdea7c balrog
#define MMC_PROFILE_BD_RE               0x0043
331 38cdea7c balrog
#define MMC_PROFILE_HDDVD_ROM           0x0050
332 38cdea7c balrog
#define MMC_PROFILE_HDDVD_R             0x0051
333 38cdea7c balrog
#define MMC_PROFILE_HDDVD_RAM           0x0052
334 38cdea7c balrog
#define MMC_PROFILE_HDDVD_RW            0x0053
335 38cdea7c balrog
#define MMC_PROFILE_HDDVD_R_DL          0x0058
336 38cdea7c balrog
#define MMC_PROFILE_HDDVD_RW_DL         0x005A
337 38cdea7c balrog
#define MMC_PROFILE_INVALID             0xFFFF
338 38cdea7c balrog
339 5391d806 bellard
#define ATAPI_INT_REASON_CD             0x01 /* 0 = data transfer */
340 5391d806 bellard
#define ATAPI_INT_REASON_IO             0x02 /* 1 = transfer to the host */
341 5391d806 bellard
#define ATAPI_INT_REASON_REL            0x04
342 5391d806 bellard
#define ATAPI_INT_REASON_TAG            0xf8
343 5391d806 bellard
344 5391d806 bellard
/* same constants as bochs */
345 7f777bf3 bellard
#define ASC_ILLEGAL_OPCODE                   0x20
346 5391d806 bellard
#define ASC_LOGICAL_BLOCK_OOR                0x21
347 5391d806 bellard
#define ASC_INV_FIELD_IN_CMD_PACKET          0x24
348 5391d806 bellard
#define ASC_MEDIUM_NOT_PRESENT               0x3a
349 5391d806 bellard
#define ASC_SAVING_PARAMETERS_NOT_SUPPORTED  0x39
350 5391d806 bellard
351 201a51fc balrog
#define CFA_NO_ERROR            0x00
352 201a51fc balrog
#define CFA_MISC_ERROR          0x09
353 201a51fc balrog
#define CFA_INVALID_COMMAND     0x20
354 201a51fc balrog
#define CFA_INVALID_ADDRESS     0x21
355 201a51fc balrog
#define CFA_ADDRESS_OVERFLOW    0x2f
356 201a51fc balrog
357 5391d806 bellard
#define SENSE_NONE            0
358 5391d806 bellard
#define SENSE_NOT_READY       2
359 5391d806 bellard
#define SENSE_ILLEGAL_REQUEST 5
360 5391d806 bellard
#define SENSE_UNIT_ATTENTION  6
361 5391d806 bellard
362 5391d806 bellard
struct IDEState;
363 5391d806 bellard
364 5391d806 bellard
typedef void EndTransferFunc(struct IDEState *);
365 5391d806 bellard
366 caed8802 bellard
/* NOTE: IDEState represents in fact one drive */
367 5391d806 bellard
typedef struct IDEState {
368 5391d806 bellard
    /* ide config */
369 5391d806 bellard
    int is_cdrom;
370 201a51fc balrog
    int is_cf;
371 5391d806 bellard
    int cylinders, heads, sectors;
372 5391d806 bellard
    int64_t nb_sectors;
373 5391d806 bellard
    int mult_sectors;
374 94458802 bellard
    int identify_set;
375 94458802 bellard
    uint16_t identify_data[256];
376 d537cf6c pbrook
    qemu_irq irq;
377 34e538ae bellard
    PCIDevice *pci_dev;
378 98087450 bellard
    struct BMDMAState *bmdma;
379 aedf5382 bellard
    int drive_serial;
380 5391d806 bellard
    /* ide regs */
381 5391d806 bellard
    uint8_t feature;
382 5391d806 bellard
    uint8_t error;
383 c2ff060f bellard
    uint32_t nsector;
384 5391d806 bellard
    uint8_t sector;
385 5391d806 bellard
    uint8_t lcyl;
386 5391d806 bellard
    uint8_t hcyl;
387 c2ff060f bellard
    /* other part of tf for lba48 support */
388 c2ff060f bellard
    uint8_t hob_feature;
389 c2ff060f bellard
    uint8_t hob_nsector;
390 c2ff060f bellard
    uint8_t hob_sector;
391 c2ff060f bellard
    uint8_t hob_lcyl;
392 c2ff060f bellard
    uint8_t hob_hcyl;
393 c2ff060f bellard
394 5391d806 bellard
    uint8_t select;
395 5391d806 bellard
    uint8_t status;
396 c2ff060f bellard
397 5391d806 bellard
    /* 0x3f6 command, only meaningful for drive 0 */
398 5391d806 bellard
    uint8_t cmd;
399 c2ff060f bellard
    /* set for lba48 access */
400 c2ff060f bellard
    uint8_t lba48;
401 5391d806 bellard
    /* depends on bit 4 in select, only meaningful for drive 0 */
402 5fafdf24 ths
    struct IDEState *cur_drive;
403 5391d806 bellard
    BlockDriverState *bs;
404 5391d806 bellard
    /* ATAPI specific */
405 5391d806 bellard
    uint8_t sense_key;
406 5391d806 bellard
    uint8_t asc;
407 5391d806 bellard
    int packet_transfer_size;
408 5391d806 bellard
    int elementary_transfer_size;
409 5391d806 bellard
    int io_buffer_index;
410 5391d806 bellard
    int lba;
411 98087450 bellard
    int cd_sector_size;
412 98087450 bellard
    int atapi_dma; /* true if dma is requested for the packet cmd */
413 98087450 bellard
    /* ATA DMA state */
414 98087450 bellard
    int io_buffer_size;
415 98087450 bellard
    /* PIO transfer handling */
416 5391d806 bellard
    int req_nb_sectors; /* number of sectors per interrupt */
417 5391d806 bellard
    EndTransferFunc *end_transfer_func;
418 5391d806 bellard
    uint8_t *data_ptr;
419 5391d806 bellard
    uint8_t *data_end;
420 33f00271 balrog
    uint8_t *io_buffer;
421 31c2a146 ths
    QEMUTimer *sector_write_timer; /* only used for win2k install hack */
422 e774a278 bellard
    uint32_t irq_count; /* counts IRQs when using win2k install hack */
423 201a51fc balrog
    /* CF-ATA extended error */
424 201a51fc balrog
    uint8_t ext_error;
425 201a51fc balrog
    /* CF-ATA metadata storage */
426 201a51fc balrog
    uint32_t mdata_size;
427 201a51fc balrog
    uint8_t *mdata_storage;
428 201a51fc balrog
    int media_changed;
429 5391d806 bellard
} IDEState;
430 5391d806 bellard
431 98087450 bellard
#define BM_STATUS_DMAING 0x01
432 98087450 bellard
#define BM_STATUS_ERROR  0x02
433 98087450 bellard
#define BM_STATUS_INT    0x04
434 98087450 bellard
435 98087450 bellard
#define BM_CMD_START     0x01
436 98087450 bellard
#define BM_CMD_READ      0x08
437 98087450 bellard
438 5457c8ce bellard
#define IDE_TYPE_PIIX3   0
439 5457c8ce bellard
#define IDE_TYPE_CMD646  1
440 afcc3cdf ths
#define IDE_TYPE_PIIX4   2
441 5457c8ce bellard
442 5457c8ce bellard
/* CMD646 specific */
443 5457c8ce bellard
#define MRDMODE                0x71
444 5457c8ce bellard
#define   MRDMODE_INTR_CH0        0x04
445 5457c8ce bellard
#define   MRDMODE_INTR_CH1        0x08
446 5457c8ce bellard
#define   MRDMODE_BLK_CH0        0x10
447 5457c8ce bellard
#define   MRDMODE_BLK_CH1        0x20
448 5457c8ce bellard
#define UDIDETCR0        0x73
449 5457c8ce bellard
#define UDIDETCR1        0x7B
450 5457c8ce bellard
451 98087450 bellard
typedef struct BMDMAState {
452 98087450 bellard
    uint8_t cmd;
453 98087450 bellard
    uint8_t status;
454 98087450 bellard
    uint32_t addr;
455 3b46e624 ths
456 5457c8ce bellard
    struct PCIIDEState *pci_dev;
457 98087450 bellard
    /* current transfer state */
458 8ccad811 bellard
    uint32_t cur_addr;
459 8ccad811 bellard
    uint32_t cur_prd_last;
460 8ccad811 bellard
    uint32_t cur_prd_addr;
461 8ccad811 bellard
    uint32_t cur_prd_len;
462 98087450 bellard
    IDEState *ide_if;
463 8ccad811 bellard
    BlockDriverCompletionFunc *dma_cb;
464 8ccad811 bellard
    BlockDriverAIOCB *aiocb;
465 98087450 bellard
} BMDMAState;
466 98087450 bellard
467 98087450 bellard
typedef struct PCIIDEState {
468 98087450 bellard
    PCIDevice dev;
469 98087450 bellard
    IDEState ide_if[4];
470 98087450 bellard
    BMDMAState bmdma[2];
471 5457c8ce bellard
    int type; /* see IDE_TYPE_xxx */
472 98087450 bellard
} PCIIDEState;
473 98087450 bellard
474 8ccad811 bellard
static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb);
475 5f12ab4b ths
static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
476 98087450 bellard
477 5391d806 bellard
static void padstr(char *str, const char *src, int len)
478 5391d806 bellard
{
479 5391d806 bellard
    int i, v;
480 5391d806 bellard
    for(i = 0; i < len; i++) {
481 5391d806 bellard
        if (*src)
482 5391d806 bellard
            v = *src++;
483 5391d806 bellard
        else
484 5391d806 bellard
            v = ' ';
485 69b34976 ths
        str[i^1] = v;
486 5391d806 bellard
    }
487 5391d806 bellard
}
488 5391d806 bellard
489 bd0d90b2 bellard
static void padstr8(uint8_t *buf, int buf_size, const char *src)
490 bd0d90b2 bellard
{
491 bd0d90b2 bellard
    int i;
492 bd0d90b2 bellard
    for(i = 0; i < buf_size; i++) {
493 bd0d90b2 bellard
        if (*src)
494 bd0d90b2 bellard
            buf[i] = *src++;
495 bd0d90b2 bellard
        else
496 bd0d90b2 bellard
            buf[i] = ' ';
497 bd0d90b2 bellard
    }
498 bd0d90b2 bellard
}
499 bd0d90b2 bellard
500 67b915a5 bellard
static void put_le16(uint16_t *p, unsigned int v)
501 67b915a5 bellard
{
502 0c4ad8dc bellard
    *p = cpu_to_le16(v);
503 67b915a5 bellard
}
504 67b915a5 bellard
505 5391d806 bellard
static void ide_identify(IDEState *s)
506 5391d806 bellard
{
507 5391d806 bellard
    uint16_t *p;
508 5391d806 bellard
    unsigned int oldsize;
509 aedf5382 bellard
    char buf[20];
510 5391d806 bellard
511 94458802 bellard
    if (s->identify_set) {
512 94458802 bellard
        memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
513 94458802 bellard
        return;
514 94458802 bellard
    }
515 94458802 bellard
516 5391d806 bellard
    memset(s->io_buffer, 0, 512);
517 5391d806 bellard
    p = (uint16_t *)s->io_buffer;
518 67b915a5 bellard
    put_le16(p + 0, 0x0040);
519 5fafdf24 ths
    put_le16(p + 1, s->cylinders);
520 67b915a5 bellard
    put_le16(p + 3, s->heads);
521 67b915a5 bellard
    put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
522 67b915a5 bellard
    put_le16(p + 5, 512); /* XXX: retired, remove ? */
523 5fafdf24 ths
    put_le16(p + 6, s->sectors);
524 aedf5382 bellard
    snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
525 60fe76f3 ths
    padstr((char *)(p + 10), buf, 20); /* serial number */
526 67b915a5 bellard
    put_le16(p + 20, 3); /* XXX: retired, remove ? */
527 67b915a5 bellard
    put_le16(p + 21, 512); /* cache size in sectors */
528 67b915a5 bellard
    put_le16(p + 22, 4); /* ecc bytes */
529 60fe76f3 ths
    padstr((char *)(p + 23), QEMU_VERSION, 8); /* firmware version */
530 60fe76f3 ths
    padstr((char *)(p + 27), "QEMU HARDDISK", 40); /* model */
531 3b46e624 ths
#if MAX_MULT_SECTORS > 1
532 67b915a5 bellard
    put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
533 5391d806 bellard
#endif
534 67b915a5 bellard
    put_le16(p + 48, 1); /* dword I/O */
535 94458802 bellard
    put_le16(p + 49, (1 << 11) | (1 << 9) | (1 << 8)); /* DMA and LBA supported */
536 67b915a5 bellard
    put_le16(p + 51, 0x200); /* PIO transfer cycle */
537 67b915a5 bellard
    put_le16(p + 52, 0x200); /* DMA transfer cycle */
538 94458802 bellard
    put_le16(p + 53, 1 | (1 << 1) | (1 << 2)); /* words 54-58,64-70,88 are valid */
539 67b915a5 bellard
    put_le16(p + 54, s->cylinders);
540 67b915a5 bellard
    put_le16(p + 55, s->heads);
541 67b915a5 bellard
    put_le16(p + 56, s->sectors);
542 5391d806 bellard
    oldsize = s->cylinders * s->heads * s->sectors;
543 67b915a5 bellard
    put_le16(p + 57, oldsize);
544 67b915a5 bellard
    put_le16(p + 58, oldsize >> 16);
545 5391d806 bellard
    if (s->mult_sectors)
546 67b915a5 bellard
        put_le16(p + 59, 0x100 | s->mult_sectors);
547 67b915a5 bellard
    put_le16(p + 60, s->nb_sectors);
548 67b915a5 bellard
    put_le16(p + 61, s->nb_sectors >> 16);
549 94458802 bellard
    put_le16(p + 63, 0x07); /* mdma0-2 supported */
550 94458802 bellard
    put_le16(p + 65, 120);
551 94458802 bellard
    put_le16(p + 66, 120);
552 94458802 bellard
    put_le16(p + 67, 120);
553 94458802 bellard
    put_le16(p + 68, 120);
554 94458802 bellard
    put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */
555 94458802 bellard
    put_le16(p + 81, 0x16); /* conforms to ata5 */
556 67b915a5 bellard
    put_le16(p + 82, (1 << 14));
557 c2ff060f bellard
    /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
558 c2ff060f bellard
    put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
559 67b915a5 bellard
    put_le16(p + 84, (1 << 14));
560 67b915a5 bellard
    put_le16(p + 85, (1 << 14));
561 c2ff060f bellard
    /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
562 c2ff060f bellard
    put_le16(p + 86, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
563 67b915a5 bellard
    put_le16(p + 87, (1 << 14));
564 94458802 bellard
    put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
565 94458802 bellard
    put_le16(p + 93, 1 | (1 << 14) | 0x2000);
566 c2ff060f bellard
    put_le16(p + 100, s->nb_sectors);
567 c2ff060f bellard
    put_le16(p + 101, s->nb_sectors >> 16);
568 c2ff060f bellard
    put_le16(p + 102, s->nb_sectors >> 32);
569 c2ff060f bellard
    put_le16(p + 103, s->nb_sectors >> 48);
570 94458802 bellard
571 94458802 bellard
    memcpy(s->identify_data, p, sizeof(s->identify_data));
572 94458802 bellard
    s->identify_set = 1;
573 5391d806 bellard
}
574 5391d806 bellard
575 5391d806 bellard
static void ide_atapi_identify(IDEState *s)
576 5391d806 bellard
{
577 5391d806 bellard
    uint16_t *p;
578 aedf5382 bellard
    char buf[20];
579 5391d806 bellard
580 94458802 bellard
    if (s->identify_set) {
581 94458802 bellard
        memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
582 94458802 bellard
        return;
583 94458802 bellard
    }
584 94458802 bellard
585 5391d806 bellard
    memset(s->io_buffer, 0, 512);
586 5391d806 bellard
    p = (uint16_t *)s->io_buffer;
587 5391d806 bellard
    /* Removable CDROM, 50us response, 12 byte packets */
588 67b915a5 bellard
    put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
589 aedf5382 bellard
    snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
590 60fe76f3 ths
    padstr((char *)(p + 10), buf, 20); /* serial number */
591 67b915a5 bellard
    put_le16(p + 20, 3); /* buffer type */
592 67b915a5 bellard
    put_le16(p + 21, 512); /* cache size in sectors */
593 67b915a5 bellard
    put_le16(p + 22, 4); /* ecc bytes */
594 60fe76f3 ths
    padstr((char *)(p + 23), QEMU_VERSION, 8); /* firmware version */
595 38cdea7c balrog
    padstr((char *)(p + 27), "QEMU DVD-ROM", 40); /* model */
596 67b915a5 bellard
    put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
597 8ccad811 bellard
#ifdef USE_DMA_CDROM
598 8ccad811 bellard
    put_le16(p + 49, 1 << 9 | 1 << 8); /* DMA and LBA supported */
599 8ccad811 bellard
    put_le16(p + 53, 7); /* words 64-70, 54-58, 88 valid */
600 8ccad811 bellard
    put_le16(p + 63, 7);  /* mdma0-2 supported */
601 8ccad811 bellard
    put_le16(p + 64, 0x3f); /* PIO modes supported */
602 8ccad811 bellard
#else
603 67b915a5 bellard
    put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
604 67b915a5 bellard
    put_le16(p + 53, 3); /* words 64-70, 54-58 valid */
605 67b915a5 bellard
    put_le16(p + 63, 0x103); /* DMA modes XXX: may be incorrect */
606 67b915a5 bellard
    put_le16(p + 64, 1); /* PIO modes */
607 8ccad811 bellard
#endif
608 67b915a5 bellard
    put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
609 67b915a5 bellard
    put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
610 67b915a5 bellard
    put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
611 67b915a5 bellard
    put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */
612 94458802 bellard
613 67b915a5 bellard
    put_le16(p + 71, 30); /* in ns */
614 67b915a5 bellard
    put_le16(p + 72, 30); /* in ns */
615 5391d806 bellard
616 67b915a5 bellard
    put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
617 8ccad811 bellard
#ifdef USE_DMA_CDROM
618 8ccad811 bellard
    put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
619 8ccad811 bellard
#endif
620 94458802 bellard
    memcpy(s->identify_data, p, sizeof(s->identify_data));
621 94458802 bellard
    s->identify_set = 1;
622 5391d806 bellard
}
623 5391d806 bellard
624 201a51fc balrog
static void ide_cfata_identify(IDEState *s)
625 201a51fc balrog
{
626 201a51fc balrog
    uint16_t *p;
627 201a51fc balrog
    uint32_t cur_sec;
628 201a51fc balrog
    char buf[20];
629 201a51fc balrog
630 201a51fc balrog
    p = (uint16_t *) s->identify_data;
631 201a51fc balrog
    if (s->identify_set)
632 201a51fc balrog
        goto fill_buffer;
633 201a51fc balrog
634 201a51fc balrog
    memset(p, 0, sizeof(s->identify_data));
635 201a51fc balrog
636 201a51fc balrog
    cur_sec = s->cylinders * s->heads * s->sectors;
637 201a51fc balrog
638 201a51fc balrog
    put_le16(p + 0, 0x848a);                        /* CF Storage Card signature */
639 201a51fc balrog
    put_le16(p + 1, s->cylinders);                /* Default cylinders */
640 201a51fc balrog
    put_le16(p + 3, s->heads);                        /* Default heads */
641 201a51fc balrog
    put_le16(p + 6, s->sectors);                /* Default sectors per track */
642 201a51fc balrog
    put_le16(p + 7, s->nb_sectors >> 16);        /* Sectors per card */
643 201a51fc balrog
    put_le16(p + 8, s->nb_sectors);                /* Sectors per card */
644 201a51fc balrog
    snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
645 60fe76f3 ths
    padstr((char *)(p + 10), buf, 20);        /* Serial number in ASCII */
646 201a51fc balrog
    put_le16(p + 22, 0x0004);                        /* ECC bytes */
647 60fe76f3 ths
    padstr((char *) (p + 23), QEMU_VERSION, 8);        /* Firmware Revision */
648 60fe76f3 ths
    padstr((char *) (p + 27), "QEMU MICRODRIVE", 40);/* Model number */
649 201a51fc balrog
#if MAX_MULT_SECTORS > 1
650 201a51fc balrog
    put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
651 201a51fc balrog
#else
652 201a51fc balrog
    put_le16(p + 47, 0x0000);
653 201a51fc balrog
#endif
654 201a51fc balrog
    put_le16(p + 49, 0x0f00);                        /* Capabilities */
655 201a51fc balrog
    put_le16(p + 51, 0x0002);                        /* PIO cycle timing mode */
656 201a51fc balrog
    put_le16(p + 52, 0x0001);                        /* DMA cycle timing mode */
657 201a51fc balrog
    put_le16(p + 53, 0x0003);                        /* Translation params valid */
658 201a51fc balrog
    put_le16(p + 54, s->cylinders);                /* Current cylinders */
659 201a51fc balrog
    put_le16(p + 55, s->heads);                        /* Current heads */
660 201a51fc balrog
    put_le16(p + 56, s->sectors);                /* Current sectors */
661 201a51fc balrog
    put_le16(p + 57, cur_sec);                        /* Current capacity */
662 201a51fc balrog
    put_le16(p + 58, cur_sec >> 16);                /* Current capacity */
663 201a51fc balrog
    if (s->mult_sectors)                        /* Multiple sector setting */
664 201a51fc balrog
        put_le16(p + 59, 0x100 | s->mult_sectors);
665 201a51fc balrog
    put_le16(p + 60, s->nb_sectors);                /* Total LBA sectors */
666 201a51fc balrog
    put_le16(p + 61, s->nb_sectors >> 16);        /* Total LBA sectors */
667 201a51fc balrog
    put_le16(p + 63, 0x0203);                        /* Multiword DMA capability */
668 201a51fc balrog
    put_le16(p + 64, 0x0001);                        /* Flow Control PIO support */
669 201a51fc balrog
    put_le16(p + 65, 0x0096);                        /* Min. Multiword DMA cycle */
670 201a51fc balrog
    put_le16(p + 66, 0x0096);                        /* Rec. Multiword DMA cycle */
671 201a51fc balrog
    put_le16(p + 68, 0x00b4);                        /* Min. PIO cycle time */
672 201a51fc balrog
    put_le16(p + 82, 0x400c);                        /* Command Set supported */
673 201a51fc balrog
    put_le16(p + 83, 0x7068);                        /* Command Set supported */
674 201a51fc balrog
    put_le16(p + 84, 0x4000);                        /* Features supported */
675 201a51fc balrog
    put_le16(p + 85, 0x000c);                        /* Command Set enabled */
676 201a51fc balrog
    put_le16(p + 86, 0x7044);                        /* Command Set enabled */
677 201a51fc balrog
    put_le16(p + 87, 0x4000);                        /* Features enabled */
678 201a51fc balrog
    put_le16(p + 91, 0x4060);                        /* Current APM level */
679 201a51fc balrog
    put_le16(p + 129, 0x0002);                        /* Current features option */
680 201a51fc balrog
    put_le16(p + 130, 0x0005);                        /* Reassigned sectors */
681 201a51fc balrog
    put_le16(p + 131, 0x0001);                        /* Initial power mode */
682 201a51fc balrog
    put_le16(p + 132, 0x0000);                        /* User signature */
683 201a51fc balrog
    put_le16(p + 160, 0x8100);                        /* Power requirement */
684 201a51fc balrog
    put_le16(p + 161, 0x8001);                        /* CF command set */
685 201a51fc balrog
686 201a51fc balrog
    s->identify_set = 1;
687 201a51fc balrog
688 201a51fc balrog
fill_buffer:
689 201a51fc balrog
    memcpy(s->io_buffer, p, sizeof(s->identify_data));
690 201a51fc balrog
}
691 201a51fc balrog
692 5391d806 bellard
static void ide_set_signature(IDEState *s)
693 5391d806 bellard
{
694 5391d806 bellard
    s->select &= 0xf0; /* clear head */
695 5391d806 bellard
    /* put signature */
696 5391d806 bellard
    s->nsector = 1;
697 5391d806 bellard
    s->sector = 1;
698 5391d806 bellard
    if (s->is_cdrom) {
699 5391d806 bellard
        s->lcyl = 0x14;
700 5391d806 bellard
        s->hcyl = 0xeb;
701 5391d806 bellard
    } else if (s->bs) {
702 5391d806 bellard
        s->lcyl = 0;
703 5391d806 bellard
        s->hcyl = 0;
704 5391d806 bellard
    } else {
705 5391d806 bellard
        s->lcyl = 0xff;
706 5391d806 bellard
        s->hcyl = 0xff;
707 5391d806 bellard
    }
708 5391d806 bellard
}
709 5391d806 bellard
710 5391d806 bellard
static inline void ide_abort_command(IDEState *s)
711 5391d806 bellard
{
712 5391d806 bellard
    s->status = READY_STAT | ERR_STAT;
713 5391d806 bellard
    s->error = ABRT_ERR;
714 5391d806 bellard
}
715 5391d806 bellard
716 5391d806 bellard
static inline void ide_set_irq(IDEState *s)
717 5391d806 bellard
{
718 98ff7d30 bellard
    BMDMAState *bm = s->bmdma;
719 5391d806 bellard
    if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) {
720 5457c8ce bellard
        if (bm) {
721 98ff7d30 bellard
            bm->status |= BM_STATUS_INT;
722 5457c8ce bellard
        }
723 d537cf6c pbrook
        qemu_irq_raise(s->irq);
724 5391d806 bellard
    }
725 5391d806 bellard
}
726 5391d806 bellard
727 5391d806 bellard
/* prepare data transfer and tell what to do after */
728 5fafdf24 ths
static void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
729 5391d806 bellard
                               EndTransferFunc *end_transfer_func)
730 5391d806 bellard
{
731 5391d806 bellard
    s->end_transfer_func = end_transfer_func;
732 5391d806 bellard
    s->data_ptr = buf;
733 5391d806 bellard
    s->data_end = buf + size;
734 7603d156 ths
    if (!(s->status & ERR_STAT))
735 7603d156 ths
        s->status |= DRQ_STAT;
736 5391d806 bellard
}
737 5391d806 bellard
738 5391d806 bellard
static void ide_transfer_stop(IDEState *s)
739 5391d806 bellard
{
740 5391d806 bellard
    s->end_transfer_func = ide_transfer_stop;
741 5391d806 bellard
    s->data_ptr = s->io_buffer;
742 5391d806 bellard
    s->data_end = s->io_buffer;
743 5391d806 bellard
    s->status &= ~DRQ_STAT;
744 5391d806 bellard
}
745 5391d806 bellard
746 5391d806 bellard
static int64_t ide_get_sector(IDEState *s)
747 5391d806 bellard
{
748 5391d806 bellard
    int64_t sector_num;
749 5391d806 bellard
    if (s->select & 0x40) {
750 5391d806 bellard
        /* lba */
751 c2ff060f bellard
        if (!s->lba48) {
752 c2ff060f bellard
            sector_num = ((s->select & 0x0f) << 24) | (s->hcyl << 16) |
753 c2ff060f bellard
                (s->lcyl << 8) | s->sector;
754 c2ff060f bellard
        } else {
755 c2ff060f bellard
            sector_num = ((int64_t)s->hob_hcyl << 40) |
756 c2ff060f bellard
                ((int64_t) s->hob_lcyl << 32) |
757 c2ff060f bellard
                ((int64_t) s->hob_sector << 24) |
758 c2ff060f bellard
                ((int64_t) s->hcyl << 16) |
759 c2ff060f bellard
                ((int64_t) s->lcyl << 8) | s->sector;
760 c2ff060f bellard
        }
761 5391d806 bellard
    } else {
762 5391d806 bellard
        sector_num = ((s->hcyl << 8) | s->lcyl) * s->heads * s->sectors +
763 c2ff060f bellard
            (s->select & 0x0f) * s->sectors + (s->sector - 1);
764 5391d806 bellard
    }
765 5391d806 bellard
    return sector_num;
766 5391d806 bellard
}
767 5391d806 bellard
768 5391d806 bellard
static void ide_set_sector(IDEState *s, int64_t sector_num)
769 5391d806 bellard
{
770 5391d806 bellard
    unsigned int cyl, r;
771 5391d806 bellard
    if (s->select & 0x40) {
772 c2ff060f bellard
        if (!s->lba48) {
773 c2ff060f bellard
            s->select = (s->select & 0xf0) | (sector_num >> 24);
774 c2ff060f bellard
            s->hcyl = (sector_num >> 16);
775 c2ff060f bellard
            s->lcyl = (sector_num >> 8);
776 c2ff060f bellard
            s->sector = (sector_num);
777 c2ff060f bellard
        } else {
778 c2ff060f bellard
            s->sector = sector_num;
779 c2ff060f bellard
            s->lcyl = sector_num >> 8;
780 c2ff060f bellard
            s->hcyl = sector_num >> 16;
781 c2ff060f bellard
            s->hob_sector = sector_num >> 24;
782 c2ff060f bellard
            s->hob_lcyl = sector_num >> 32;
783 c2ff060f bellard
            s->hob_hcyl = sector_num >> 40;
784 c2ff060f bellard
        }
785 5391d806 bellard
    } else {
786 5391d806 bellard
        cyl = sector_num / (s->heads * s->sectors);
787 5391d806 bellard
        r = sector_num % (s->heads * s->sectors);
788 5391d806 bellard
        s->hcyl = cyl >> 8;
789 5391d806 bellard
        s->lcyl = cyl;
790 1b8eb456 bellard
        s->select = (s->select & 0xf0) | ((r / s->sectors) & 0x0f);
791 5391d806 bellard
        s->sector = (r % s->sectors) + 1;
792 5391d806 bellard
    }
793 5391d806 bellard
}
794 5391d806 bellard
795 5391d806 bellard
static void ide_sector_read(IDEState *s)
796 5391d806 bellard
{
797 5391d806 bellard
    int64_t sector_num;
798 5391d806 bellard
    int ret, n;
799 5391d806 bellard
800 5391d806 bellard
    s->status = READY_STAT | SEEK_STAT;
801 a136e5a8 bellard
    s->error = 0; /* not needed by IDE spec, but needed by Windows */
802 5391d806 bellard
    sector_num = ide_get_sector(s);
803 5391d806 bellard
    n = s->nsector;
804 5391d806 bellard
    if (n == 0) {
805 5391d806 bellard
        /* no more sector to read from disk */
806 5391d806 bellard
        ide_transfer_stop(s);
807 5391d806 bellard
    } else {
808 5391d806 bellard
#if defined(DEBUG_IDE)
809 5391d806 bellard
        printf("read sector=%Ld\n", sector_num);
810 5391d806 bellard
#endif
811 5391d806 bellard
        if (n > s->req_nb_sectors)
812 5391d806 bellard
            n = s->req_nb_sectors;
813 5391d806 bellard
        ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
814 5391d806 bellard
        ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
815 5391d806 bellard
        ide_set_irq(s);
816 5391d806 bellard
        ide_set_sector(s, sector_num + n);
817 5391d806 bellard
        s->nsector -= n;
818 5391d806 bellard
    }
819 5391d806 bellard
}
820 5391d806 bellard
821 8ccad811 bellard
/* return 0 if buffer completed */
822 8ccad811 bellard
static int dma_buf_rw(BMDMAState *bm, int is_write)
823 98087450 bellard
{
824 8ccad811 bellard
    IDEState *s = bm->ide_if;
825 8ccad811 bellard
    struct {
826 8ccad811 bellard
        uint32_t addr;
827 8ccad811 bellard
        uint32_t size;
828 8ccad811 bellard
    } prd;
829 8ccad811 bellard
    int l, len;
830 98087450 bellard
831 8ccad811 bellard
    for(;;) {
832 8ccad811 bellard
        l = s->io_buffer_size - s->io_buffer_index;
833 5fafdf24 ths
        if (l <= 0)
834 8ccad811 bellard
            break;
835 8ccad811 bellard
        if (bm->cur_prd_len == 0) {
836 8ccad811 bellard
            /* end of table (with a fail safe of one page) */
837 8ccad811 bellard
            if (bm->cur_prd_last ||
838 8ccad811 bellard
                (bm->cur_addr - bm->addr) >= 4096)
839 8ccad811 bellard
                return 0;
840 8ccad811 bellard
            cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8);
841 8ccad811 bellard
            bm->cur_addr += 8;
842 8ccad811 bellard
            prd.addr = le32_to_cpu(prd.addr);
843 8ccad811 bellard
            prd.size = le32_to_cpu(prd.size);
844 8ccad811 bellard
            len = prd.size & 0xfffe;
845 8ccad811 bellard
            if (len == 0)
846 8ccad811 bellard
                len = 0x10000;
847 8ccad811 bellard
            bm->cur_prd_len = len;
848 8ccad811 bellard
            bm->cur_prd_addr = prd.addr;
849 8ccad811 bellard
            bm->cur_prd_last = (prd.size & 0x80000000);
850 8ccad811 bellard
        }
851 8ccad811 bellard
        if (l > bm->cur_prd_len)
852 8ccad811 bellard
            l = bm->cur_prd_len;
853 8ccad811 bellard
        if (l > 0) {
854 8ccad811 bellard
            if (is_write) {
855 5fafdf24 ths
                cpu_physical_memory_write(bm->cur_prd_addr,
856 8ccad811 bellard
                                          s->io_buffer + s->io_buffer_index, l);
857 8ccad811 bellard
            } else {
858 5fafdf24 ths
                cpu_physical_memory_read(bm->cur_prd_addr,
859 8ccad811 bellard
                                          s->io_buffer + s->io_buffer_index, l);
860 8ccad811 bellard
            }
861 8ccad811 bellard
            bm->cur_prd_addr += l;
862 8ccad811 bellard
            bm->cur_prd_len -= l;
863 8ccad811 bellard
            s->io_buffer_index += l;
864 98087450 bellard
        }
865 98087450 bellard
    }
866 8ccad811 bellard
    return 1;
867 8ccad811 bellard
}
868 8ccad811 bellard
869 8ccad811 bellard
/* XXX: handle errors */
870 8ccad811 bellard
static void ide_read_dma_cb(void *opaque, int ret)
871 8ccad811 bellard
{
872 8ccad811 bellard
    BMDMAState *bm = opaque;
873 8ccad811 bellard
    IDEState *s = bm->ide_if;
874 8ccad811 bellard
    int n;
875 8ccad811 bellard
    int64_t sector_num;
876 8ccad811 bellard
877 8ccad811 bellard
    n = s->io_buffer_size >> 9;
878 8ccad811 bellard
    sector_num = ide_get_sector(s);
879 8ccad811 bellard
    if (n > 0) {
880 8ccad811 bellard
        sector_num += n;
881 8ccad811 bellard
        ide_set_sector(s, sector_num);
882 8ccad811 bellard
        s->nsector -= n;
883 8ccad811 bellard
        if (dma_buf_rw(bm, 1) == 0)
884 8ccad811 bellard
            goto eot;
885 8ccad811 bellard
    }
886 8ccad811 bellard
887 8ccad811 bellard
    /* end of transfer ? */
888 8ccad811 bellard
    if (s->nsector == 0) {
889 98087450 bellard
        s->status = READY_STAT | SEEK_STAT;
890 98087450 bellard
        ide_set_irq(s);
891 8ccad811 bellard
    eot:
892 8ccad811 bellard
        bm->status &= ~BM_STATUS_DMAING;
893 8ccad811 bellard
        bm->status |= BM_STATUS_INT;
894 8ccad811 bellard
        bm->dma_cb = NULL;
895 8ccad811 bellard
        bm->ide_if = NULL;
896 8ccad811 bellard
        bm->aiocb = NULL;
897 8ccad811 bellard
        return;
898 98087450 bellard
    }
899 8ccad811 bellard
900 8ccad811 bellard
    /* launch next transfer */
901 8ccad811 bellard
    n = s->nsector;
902 8ccad811 bellard
    if (n > MAX_MULT_SECTORS)
903 8ccad811 bellard
        n = MAX_MULT_SECTORS;
904 8ccad811 bellard
    s->io_buffer_index = 0;
905 8ccad811 bellard
    s->io_buffer_size = n * 512;
906 8ccad811 bellard
#ifdef DEBUG_AIO
907 8ccad811 bellard
    printf("aio_read: sector_num=%lld n=%d\n", sector_num, n);
908 8ccad811 bellard
#endif
909 5fafdf24 ths
    bm->aiocb = bdrv_aio_read(s->bs, sector_num, s->io_buffer, n,
910 8ccad811 bellard
                              ide_read_dma_cb, bm);
911 98087450 bellard
}
912 98087450 bellard
913 98087450 bellard
static void ide_sector_read_dma(IDEState *s)
914 98087450 bellard
{
915 8ccad811 bellard
    s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
916 98087450 bellard
    s->io_buffer_index = 0;
917 98087450 bellard
    s->io_buffer_size = 0;
918 98087450 bellard
    ide_dma_start(s, ide_read_dma_cb);
919 98087450 bellard
}
920 98087450 bellard
921 a09db21f bellard
static void ide_sector_write_timer_cb(void *opaque)
922 a09db21f bellard
{
923 a09db21f bellard
    IDEState *s = opaque;
924 a09db21f bellard
    ide_set_irq(s);
925 a09db21f bellard
}
926 a09db21f bellard
927 5391d806 bellard
static void ide_sector_write(IDEState *s)
928 5391d806 bellard
{
929 5391d806 bellard
    int64_t sector_num;
930 31c2a146 ths
    int ret, n, n1;
931 5391d806 bellard
932 5391d806 bellard
    s->status = READY_STAT | SEEK_STAT;
933 5391d806 bellard
    sector_num = ide_get_sector(s);
934 5391d806 bellard
#if defined(DEBUG_IDE)
935 5391d806 bellard
    printf("write sector=%Ld\n", sector_num);
936 5391d806 bellard
#endif
937 5391d806 bellard
    n = s->nsector;
938 5391d806 bellard
    if (n > s->req_nb_sectors)
939 5391d806 bellard
        n = s->req_nb_sectors;
940 31c2a146 ths
    ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
941 5391d806 bellard
    s->nsector -= n;
942 5391d806 bellard
    if (s->nsector == 0) {
943 292eef5a ths
        /* no more sectors to write */
944 5391d806 bellard
        ide_transfer_stop(s);
945 5391d806 bellard
    } else {
946 5391d806 bellard
        n1 = s->nsector;
947 5391d806 bellard
        if (n1 > s->req_nb_sectors)
948 5391d806 bellard
            n1 = s->req_nb_sectors;
949 5391d806 bellard
        ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
950 5391d806 bellard
    }
951 5391d806 bellard
    ide_set_sector(s, sector_num + n);
952 3b46e624 ths
953 31c2a146 ths
#ifdef TARGET_I386
954 31c2a146 ths
    if (win2k_install_hack && ((++s->irq_count % 16) == 0)) {
955 31c2a146 ths
        /* It seems there is a bug in the Windows 2000 installer HDD
956 31c2a146 ths
           IDE driver which fills the disk with empty logs when the
957 31c2a146 ths
           IDE write IRQ comes too early. This hack tries to correct
958 31c2a146 ths
           that at the expense of slower write performances. Use this
959 31c2a146 ths
           option _only_ to install Windows 2000. You must disable it
960 31c2a146 ths
           for normal use. */
961 31c2a146 ths
        qemu_mod_timer(s->sector_write_timer, 
962 31c2a146 ths
                       qemu_get_clock(vm_clock) + (ticks_per_sec / 1000));
963 31c2a146 ths
    } else 
964 31c2a146 ths
#endif
965 31c2a146 ths
    {
966 31c2a146 ths
        ide_set_irq(s);
967 31c2a146 ths
    }
968 5391d806 bellard
}
969 5391d806 bellard
970 8ccad811 bellard
/* XXX: handle errors */
971 8ccad811 bellard
static void ide_write_dma_cb(void *opaque, int ret)
972 98087450 bellard
{
973 8ccad811 bellard
    BMDMAState *bm = opaque;
974 8ccad811 bellard
    IDEState *s = bm->ide_if;
975 8ccad811 bellard
    int n;
976 98087450 bellard
    int64_t sector_num;
977 98087450 bellard
978 8ccad811 bellard
    n = s->io_buffer_size >> 9;
979 8ccad811 bellard
    sector_num = ide_get_sector(s);
980 8ccad811 bellard
    if (n > 0) {
981 8ccad811 bellard
        sector_num += n;
982 8ccad811 bellard
        ide_set_sector(s, sector_num);
983 8ccad811 bellard
        s->nsector -= n;
984 98087450 bellard
    }
985 98087450 bellard
986 8ccad811 bellard
    /* end of transfer ? */
987 8ccad811 bellard
    if (s->nsector == 0) {
988 8ccad811 bellard
        s->status = READY_STAT | SEEK_STAT;
989 8ccad811 bellard
        ide_set_irq(s);
990 8ccad811 bellard
    eot:
991 8ccad811 bellard
        bm->status &= ~BM_STATUS_DMAING;
992 8ccad811 bellard
        bm->status |= BM_STATUS_INT;
993 8ccad811 bellard
        bm->dma_cb = NULL;
994 8ccad811 bellard
        bm->ide_if = NULL;
995 8ccad811 bellard
        bm->aiocb = NULL;
996 8ccad811 bellard
        return;
997 8ccad811 bellard
    }
998 8ccad811 bellard
999 8ccad811 bellard
    /* launch next transfer */
1000 98087450 bellard
    n = s->nsector;
1001 98087450 bellard
    if (n > MAX_MULT_SECTORS)
1002 98087450 bellard
        n = MAX_MULT_SECTORS;
1003 98087450 bellard
    s->io_buffer_index = 0;
1004 98087450 bellard
    s->io_buffer_size = n * 512;
1005 8ccad811 bellard
1006 8ccad811 bellard
    if (dma_buf_rw(bm, 0) == 0)
1007 8ccad811 bellard
        goto eot;
1008 8ccad811 bellard
#ifdef DEBUG_AIO
1009 8ccad811 bellard
    printf("aio_write: sector_num=%lld n=%d\n", sector_num, n);
1010 8ccad811 bellard
#endif
1011 5fafdf24 ths
    bm->aiocb = bdrv_aio_write(s->bs, sector_num, s->io_buffer, n,
1012 8ccad811 bellard
                               ide_write_dma_cb, bm);
1013 8ccad811 bellard
}
1014 8ccad811 bellard
1015 8ccad811 bellard
static void ide_sector_write_dma(IDEState *s)
1016 8ccad811 bellard
{
1017 8ccad811 bellard
    s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
1018 8ccad811 bellard
    s->io_buffer_index = 0;
1019 8ccad811 bellard
    s->io_buffer_size = 0;
1020 98087450 bellard
    ide_dma_start(s, ide_write_dma_cb);
1021 98087450 bellard
}
1022 98087450 bellard
1023 5391d806 bellard
static void ide_atapi_cmd_ok(IDEState *s)
1024 5391d806 bellard
{
1025 5391d806 bellard
    s->error = 0;
1026 5391d806 bellard
    s->status = READY_STAT;
1027 5391d806 bellard
    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1028 5391d806 bellard
    ide_set_irq(s);
1029 5391d806 bellard
}
1030 5391d806 bellard
1031 5391d806 bellard
static void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
1032 5391d806 bellard
{
1033 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1034 5391d806 bellard
    printf("atapi_cmd_error: sense=0x%x asc=0x%x\n", sense_key, asc);
1035 5391d806 bellard
#endif
1036 5391d806 bellard
    s->error = sense_key << 4;
1037 5391d806 bellard
    s->status = READY_STAT | ERR_STAT;
1038 5391d806 bellard
    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1039 5391d806 bellard
    s->sense_key = sense_key;
1040 5391d806 bellard
    s->asc = asc;
1041 5391d806 bellard
    ide_set_irq(s);
1042 5391d806 bellard
}
1043 5391d806 bellard
1044 5391d806 bellard
static inline void cpu_to_ube16(uint8_t *buf, int val)
1045 5391d806 bellard
{
1046 5391d806 bellard
    buf[0] = val >> 8;
1047 5391d806 bellard
    buf[1] = val;
1048 5391d806 bellard
}
1049 5391d806 bellard
1050 5391d806 bellard
static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
1051 5391d806 bellard
{
1052 5391d806 bellard
    buf[0] = val >> 24;
1053 5391d806 bellard
    buf[1] = val >> 16;
1054 5391d806 bellard
    buf[2] = val >> 8;
1055 5391d806 bellard
    buf[3] = val;
1056 5391d806 bellard
}
1057 5391d806 bellard
1058 5391d806 bellard
static inline int ube16_to_cpu(const uint8_t *buf)
1059 5391d806 bellard
{
1060 5391d806 bellard
    return (buf[0] << 8) | buf[1];
1061 5391d806 bellard
}
1062 5391d806 bellard
1063 5391d806 bellard
static inline int ube32_to_cpu(const uint8_t *buf)
1064 5391d806 bellard
{
1065 5391d806 bellard
    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1066 5391d806 bellard
}
1067 5391d806 bellard
1068 98087450 bellard
static void lba_to_msf(uint8_t *buf, int lba)
1069 98087450 bellard
{
1070 98087450 bellard
    lba += 150;
1071 98087450 bellard
    buf[0] = (lba / 75) / 60;
1072 98087450 bellard
    buf[1] = (lba / 75) % 60;
1073 98087450 bellard
    buf[2] = lba % 75;
1074 98087450 bellard
}
1075 98087450 bellard
1076 8ccad811 bellard
static void cd_data_to_raw(uint8_t *buf, int lba)
1077 8ccad811 bellard
{
1078 8ccad811 bellard
    /* sync bytes */
1079 8ccad811 bellard
    buf[0] = 0x00;
1080 8ccad811 bellard
    memset(buf + 1, 0xff, 10);
1081 8ccad811 bellard
    buf[11] = 0x00;
1082 8ccad811 bellard
    buf += 12;
1083 8ccad811 bellard
    /* MSF */
1084 8ccad811 bellard
    lba_to_msf(buf, lba);
1085 8ccad811 bellard
    buf[3] = 0x01; /* mode 1 data */
1086 8ccad811 bellard
    buf += 4;
1087 8ccad811 bellard
    /* data */
1088 8ccad811 bellard
    buf += 2048;
1089 8ccad811 bellard
    /* XXX: ECC not computed */
1090 8ccad811 bellard
    memset(buf, 0, 288);
1091 8ccad811 bellard
}
1092 8ccad811 bellard
1093 5fafdf24 ths
static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
1094 98087450 bellard
                           int sector_size)
1095 98087450 bellard
{
1096 66c6ef76 bellard
    int ret;
1097 66c6ef76 bellard
1098 98087450 bellard
    switch(sector_size) {
1099 98087450 bellard
    case 2048:
1100 66c6ef76 bellard
        ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4);
1101 98087450 bellard
        break;
1102 98087450 bellard
    case 2352:
1103 66c6ef76 bellard
        ret = bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
1104 66c6ef76 bellard
        if (ret < 0)
1105 66c6ef76 bellard
            return ret;
1106 8ccad811 bellard
        cd_data_to_raw(buf, lba);
1107 98087450 bellard
        break;
1108 98087450 bellard
    default:
1109 66c6ef76 bellard
        ret = -EIO;
1110 98087450 bellard
        break;
1111 98087450 bellard
    }
1112 66c6ef76 bellard
    return ret;
1113 66c6ef76 bellard
}
1114 66c6ef76 bellard
1115 66c6ef76 bellard
static void ide_atapi_io_error(IDEState *s, int ret)
1116 66c6ef76 bellard
{
1117 66c6ef76 bellard
    /* XXX: handle more errors */
1118 66c6ef76 bellard
    if (ret == -ENOMEDIUM) {
1119 5fafdf24 ths
        ide_atapi_cmd_error(s, SENSE_NOT_READY,
1120 66c6ef76 bellard
                            ASC_MEDIUM_NOT_PRESENT);
1121 66c6ef76 bellard
    } else {
1122 5fafdf24 ths
        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1123 66c6ef76 bellard
                            ASC_LOGICAL_BLOCK_OOR);
1124 66c6ef76 bellard
    }
1125 98087450 bellard
}
1126 98087450 bellard
1127 5391d806 bellard
/* The whole ATAPI transfer logic is handled in this function */
1128 5391d806 bellard
static void ide_atapi_cmd_reply_end(IDEState *s)
1129 5391d806 bellard
{
1130 66c6ef76 bellard
    int byte_count_limit, size, ret;
1131 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1132 5fafdf24 ths
    printf("reply: tx_size=%d elem_tx_size=%d index=%d\n",
1133 5391d806 bellard
           s->packet_transfer_size,
1134 5391d806 bellard
           s->elementary_transfer_size,
1135 5391d806 bellard
           s->io_buffer_index);
1136 5391d806 bellard
#endif
1137 5391d806 bellard
    if (s->packet_transfer_size <= 0) {
1138 5391d806 bellard
        /* end of transfer */
1139 5391d806 bellard
        ide_transfer_stop(s);
1140 5391d806 bellard
        s->status = READY_STAT;
1141 5391d806 bellard
        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1142 5391d806 bellard
        ide_set_irq(s);
1143 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1144 5391d806 bellard
        printf("status=0x%x\n", s->status);
1145 5391d806 bellard
#endif
1146 5391d806 bellard
    } else {
1147 5391d806 bellard
        /* see if a new sector must be read */
1148 98087450 bellard
        if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
1149 66c6ef76 bellard
            ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
1150 66c6ef76 bellard
            if (ret < 0) {
1151 66c6ef76 bellard
                ide_transfer_stop(s);
1152 66c6ef76 bellard
                ide_atapi_io_error(s, ret);
1153 66c6ef76 bellard
                return;
1154 66c6ef76 bellard
            }
1155 5391d806 bellard
            s->lba++;
1156 5391d806 bellard
            s->io_buffer_index = 0;
1157 5391d806 bellard
        }
1158 5391d806 bellard
        if (s->elementary_transfer_size > 0) {
1159 5391d806 bellard
            /* there are some data left to transmit in this elementary
1160 5391d806 bellard
               transfer */
1161 98087450 bellard
            size = s->cd_sector_size - s->io_buffer_index;
1162 5391d806 bellard
            if (size > s->elementary_transfer_size)
1163 5391d806 bellard
                size = s->elementary_transfer_size;
1164 5fafdf24 ths
            ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
1165 5391d806 bellard
                               size, ide_atapi_cmd_reply_end);
1166 5391d806 bellard
            s->packet_transfer_size -= size;
1167 5391d806 bellard
            s->elementary_transfer_size -= size;
1168 5391d806 bellard
            s->io_buffer_index += size;
1169 5391d806 bellard
        } else {
1170 5391d806 bellard
            /* a new transfer is needed */
1171 5391d806 bellard
            s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
1172 5391d806 bellard
            byte_count_limit = s->lcyl | (s->hcyl << 8);
1173 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1174 5391d806 bellard
            printf("byte_count_limit=%d\n", byte_count_limit);
1175 5391d806 bellard
#endif
1176 5391d806 bellard
            if (byte_count_limit == 0xffff)
1177 5391d806 bellard
                byte_count_limit--;
1178 5391d806 bellard
            size = s->packet_transfer_size;
1179 5391d806 bellard
            if (size > byte_count_limit) {
1180 5391d806 bellard
                /* byte count limit must be even if this case */
1181 5391d806 bellard
                if (byte_count_limit & 1)
1182 5391d806 bellard
                    byte_count_limit--;
1183 5391d806 bellard
                size = byte_count_limit;
1184 5391d806 bellard
            }
1185 a136e5a8 bellard
            s->lcyl = size;
1186 a136e5a8 bellard
            s->hcyl = size >> 8;
1187 5391d806 bellard
            s->elementary_transfer_size = size;
1188 5391d806 bellard
            /* we cannot transmit more than one sector at a time */
1189 5391d806 bellard
            if (s->lba != -1) {
1190 98087450 bellard
                if (size > (s->cd_sector_size - s->io_buffer_index))
1191 98087450 bellard
                    size = (s->cd_sector_size - s->io_buffer_index);
1192 5391d806 bellard
            }
1193 5fafdf24 ths
            ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
1194 5391d806 bellard
                               size, ide_atapi_cmd_reply_end);
1195 5391d806 bellard
            s->packet_transfer_size -= size;
1196 5391d806 bellard
            s->elementary_transfer_size -= size;
1197 5391d806 bellard
            s->io_buffer_index += size;
1198 5391d806 bellard
            ide_set_irq(s);
1199 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1200 5391d806 bellard
            printf("status=0x%x\n", s->status);
1201 5391d806 bellard
#endif
1202 5391d806 bellard
        }
1203 5391d806 bellard
    }
1204 5391d806 bellard
}
1205 5391d806 bellard
1206 5391d806 bellard
/* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
1207 5391d806 bellard
static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
1208 5391d806 bellard
{
1209 5391d806 bellard
    if (size > max_size)
1210 5391d806 bellard
        size = max_size;
1211 5391d806 bellard
    s->lba = -1; /* no sector read */
1212 5391d806 bellard
    s->packet_transfer_size = size;
1213 5f12ab4b ths
    s->io_buffer_size = size;    /* dma: send the reply data as one chunk */
1214 5391d806 bellard
    s->elementary_transfer_size = 0;
1215 5391d806 bellard
    s->io_buffer_index = 0;
1216 5391d806 bellard
1217 5f12ab4b ths
    if (s->atapi_dma) {
1218 5f12ab4b ths
            s->status = READY_STAT | DRQ_STAT;
1219 5f12ab4b ths
        ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
1220 5f12ab4b ths
    } else {
1221 5f12ab4b ths
            s->status = READY_STAT;
1222 5f12ab4b ths
            ide_atapi_cmd_reply_end(s);
1223 5f12ab4b ths
    }
1224 5391d806 bellard
}
1225 5391d806 bellard
1226 5391d806 bellard
/* start a CD-CDROM read command */
1227 98087450 bellard
static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
1228 98087450 bellard
                                   int sector_size)
1229 5391d806 bellard
{
1230 5391d806 bellard
    s->lba = lba;
1231 98087450 bellard
    s->packet_transfer_size = nb_sectors * sector_size;
1232 5391d806 bellard
    s->elementary_transfer_size = 0;
1233 98087450 bellard
    s->io_buffer_index = sector_size;
1234 98087450 bellard
    s->cd_sector_size = sector_size;
1235 5391d806 bellard
1236 5391d806 bellard
    s->status = READY_STAT;
1237 5391d806 bellard
    ide_atapi_cmd_reply_end(s);
1238 5391d806 bellard
}
1239 5391d806 bellard
1240 98087450 bellard
/* ATAPI DMA support */
1241 8ccad811 bellard
1242 8ccad811 bellard
/* XXX: handle read errors */
1243 8ccad811 bellard
static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
1244 98087450 bellard
{
1245 8ccad811 bellard
    BMDMAState *bm = opaque;
1246 8ccad811 bellard
    IDEState *s = bm->ide_if;
1247 8ccad811 bellard
    int data_offset, n;
1248 8ccad811 bellard
1249 66c6ef76 bellard
    if (ret < 0) {
1250 66c6ef76 bellard
        ide_atapi_io_error(s, ret);
1251 66c6ef76 bellard
        goto eot;
1252 66c6ef76 bellard
    }
1253 66c6ef76 bellard
1254 8ccad811 bellard
    if (s->io_buffer_size > 0) {
1255 5f12ab4b ths
        /*
1256 5f12ab4b ths
         * For a cdrom read sector command (s->lba != -1),
1257 5f12ab4b ths
         * adjust the lba for the next s->io_buffer_size chunk
1258 5f12ab4b ths
         * and dma the current chunk.
1259 5f12ab4b ths
         * For a command != read (s->lba == -1), just transfer
1260 5f12ab4b ths
         * the reply data.
1261 5f12ab4b ths
         */
1262 5f12ab4b ths
        if (s->lba != -1) {
1263 5f12ab4b ths
            if (s->cd_sector_size == 2352) {
1264 5f12ab4b ths
                n = 1;
1265 5f12ab4b ths
                cd_data_to_raw(s->io_buffer, s->lba);
1266 5f12ab4b ths
            } else {
1267 5f12ab4b ths
                n = s->io_buffer_size >> 11;
1268 5f12ab4b ths
            }
1269 5f12ab4b ths
            s->lba += n;
1270 5f12ab4b ths
        }
1271 8ccad811 bellard
        s->packet_transfer_size -= s->io_buffer_size;
1272 8ccad811 bellard
        if (dma_buf_rw(bm, 1) == 0)
1273 8ccad811 bellard
            goto eot;
1274 98087450 bellard
    }
1275 8ccad811 bellard
1276 98087450 bellard
    if (s->packet_transfer_size <= 0) {
1277 98087450 bellard
        s->status = READY_STAT;
1278 98087450 bellard
        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1279 98087450 bellard
        ide_set_irq(s);
1280 8ccad811 bellard
    eot:
1281 8ccad811 bellard
        bm->status &= ~BM_STATUS_DMAING;
1282 8ccad811 bellard
        bm->status |= BM_STATUS_INT;
1283 8ccad811 bellard
        bm->dma_cb = NULL;
1284 8ccad811 bellard
        bm->ide_if = NULL;
1285 8ccad811 bellard
        bm->aiocb = NULL;
1286 8ccad811 bellard
        return;
1287 8ccad811 bellard
    }
1288 3b46e624 ths
1289 8ccad811 bellard
    s->io_buffer_index = 0;
1290 8ccad811 bellard
    if (s->cd_sector_size == 2352) {
1291 8ccad811 bellard
        n = 1;
1292 8ccad811 bellard
        s->io_buffer_size = s->cd_sector_size;
1293 8ccad811 bellard
        data_offset = 16;
1294 8ccad811 bellard
    } else {
1295 8ccad811 bellard
        n = s->packet_transfer_size >> 11;
1296 8ccad811 bellard
        if (n > (MAX_MULT_SECTORS / 4))
1297 8ccad811 bellard
            n = (MAX_MULT_SECTORS / 4);
1298 8ccad811 bellard
        s->io_buffer_size = n * 2048;
1299 8ccad811 bellard
        data_offset = 0;
1300 98087450 bellard
    }
1301 8ccad811 bellard
#ifdef DEBUG_AIO
1302 8ccad811 bellard
    printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
1303 8ccad811 bellard
#endif
1304 5fafdf24 ths
    bm->aiocb = bdrv_aio_read(s->bs, (int64_t)s->lba << 2,
1305 5fafdf24 ths
                              s->io_buffer + data_offset, n * 4,
1306 8ccad811 bellard
                              ide_atapi_cmd_read_dma_cb, bm);
1307 66c6ef76 bellard
    if (!bm->aiocb) {
1308 66c6ef76 bellard
        /* Note: media not present is the most likely case */
1309 5fafdf24 ths
        ide_atapi_cmd_error(s, SENSE_NOT_READY,
1310 66c6ef76 bellard
                            ASC_MEDIUM_NOT_PRESENT);
1311 66c6ef76 bellard
        goto eot;
1312 66c6ef76 bellard
    }
1313 98087450 bellard
}
1314 98087450 bellard
1315 98087450 bellard
/* start a CD-CDROM read command with DMA */
1316 98087450 bellard
/* XXX: test if DMA is available */
1317 98087450 bellard
static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
1318 98087450 bellard
                                   int sector_size)
1319 98087450 bellard
{
1320 98087450 bellard
    s->lba = lba;
1321 98087450 bellard
    s->packet_transfer_size = nb_sectors * sector_size;
1322 8ccad811 bellard
    s->io_buffer_index = 0;
1323 8ccad811 bellard
    s->io_buffer_size = 0;
1324 98087450 bellard
    s->cd_sector_size = sector_size;
1325 98087450 bellard
1326 8ccad811 bellard
    /* XXX: check if BUSY_STAT should be set */
1327 8ccad811 bellard
    s->status = READY_STAT | DRQ_STAT | BUSY_STAT;
1328 98087450 bellard
    ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
1329 98087450 bellard
}
1330 98087450 bellard
1331 5fafdf24 ths
static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
1332 98087450 bellard
                               int sector_size)
1333 98087450 bellard
{
1334 98087450 bellard
#ifdef DEBUG_IDE_ATAPI
1335 5f12ab4b ths
    printf("read %s: LBA=%d nb_sectors=%d\n", s->atapi_dma ? "dma" : "pio",
1336 5f12ab4b ths
        lba, nb_sectors);
1337 98087450 bellard
#endif
1338 98087450 bellard
    if (s->atapi_dma) {
1339 98087450 bellard
        ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
1340 98087450 bellard
    } else {
1341 98087450 bellard
        ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size);
1342 98087450 bellard
    }
1343 98087450 bellard
}
1344 98087450 bellard
1345 38cdea7c balrog
static inline uint8_t ide_atapi_set_profile(uint8_t *buf, uint8_t *index,
1346 38cdea7c balrog
                                            uint16_t profile)
1347 38cdea7c balrog
{
1348 38cdea7c balrog
    uint8_t *buf_profile = buf + 12; /* start of profiles */
1349 38cdea7c balrog
1350 38cdea7c balrog
    buf_profile += ((*index) * 4); /* start of indexed profile */
1351 38cdea7c balrog
    cpu_to_ube16 (buf_profile, profile);
1352 38cdea7c balrog
    buf_profile[2] = ((buf_profile[0] == buf[6]) && (buf_profile[1] == buf[7]));
1353 38cdea7c balrog
1354 38cdea7c balrog
    /* each profile adds 4 bytes to the response */
1355 38cdea7c balrog
    (*index)++;
1356 38cdea7c balrog
    buf[11] += 4; /* Additional Length */
1357 38cdea7c balrog
1358 38cdea7c balrog
    return 4;
1359 38cdea7c balrog
}
1360 38cdea7c balrog
1361 5391d806 bellard
static void ide_atapi_cmd(IDEState *s)
1362 5391d806 bellard
{
1363 5391d806 bellard
    const uint8_t *packet;
1364 5391d806 bellard
    uint8_t *buf;
1365 5391d806 bellard
    int max_len;
1366 5391d806 bellard
1367 5391d806 bellard
    packet = s->io_buffer;
1368 5391d806 bellard
    buf = s->io_buffer;
1369 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1370 5391d806 bellard
    {
1371 5391d806 bellard
        int i;
1372 5391d806 bellard
        printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
1373 5391d806 bellard
        for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
1374 5391d806 bellard
            printf(" %02x", packet[i]);
1375 5391d806 bellard
        }
1376 5391d806 bellard
        printf("\n");
1377 5391d806 bellard
    }
1378 5391d806 bellard
#endif
1379 5391d806 bellard
    switch(s->io_buffer[0]) {
1380 5391d806 bellard
    case GPCMD_TEST_UNIT_READY:
1381 caed8802 bellard
        if (bdrv_is_inserted(s->bs)) {
1382 5391d806 bellard
            ide_atapi_cmd_ok(s);
1383 5391d806 bellard
        } else {
1384 5fafdf24 ths
            ide_atapi_cmd_error(s, SENSE_NOT_READY,
1385 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1386 5391d806 bellard
        }
1387 5391d806 bellard
        break;
1388 d14049ea ths
    case GPCMD_MODE_SENSE_6:
1389 5391d806 bellard
    case GPCMD_MODE_SENSE_10:
1390 5391d806 bellard
        {
1391 5391d806 bellard
            int action, code;
1392 d14049ea ths
            if (packet[0] == GPCMD_MODE_SENSE_10)
1393 d14049ea ths
                max_len = ube16_to_cpu(packet + 7);
1394 d14049ea ths
            else
1395 d14049ea ths
                max_len = packet[4];
1396 5391d806 bellard
            action = packet[2] >> 6;
1397 5391d806 bellard
            code = packet[2] & 0x3f;
1398 5391d806 bellard
            switch(action) {
1399 5391d806 bellard
            case 0: /* current values */
1400 5391d806 bellard
                switch(code) {
1401 5391d806 bellard
                case 0x01: /* error recovery */
1402 5391d806 bellard
                    cpu_to_ube16(&buf[0], 16 + 6);
1403 5391d806 bellard
                    buf[2] = 0x70;
1404 5391d806 bellard
                    buf[3] = 0;
1405 5391d806 bellard
                    buf[4] = 0;
1406 5391d806 bellard
                    buf[5] = 0;
1407 5391d806 bellard
                    buf[6] = 0;
1408 5391d806 bellard
                    buf[7] = 0;
1409 5391d806 bellard
1410 5391d806 bellard
                    buf[8] = 0x01;
1411 5391d806 bellard
                    buf[9] = 0x06;
1412 5391d806 bellard
                    buf[10] = 0x00;
1413 5391d806 bellard
                    buf[11] = 0x05;
1414 5391d806 bellard
                    buf[12] = 0x00;
1415 5391d806 bellard
                    buf[13] = 0x00;
1416 5391d806 bellard
                    buf[14] = 0x00;
1417 5391d806 bellard
                    buf[15] = 0x00;
1418 5391d806 bellard
                    ide_atapi_cmd_reply(s, 16, max_len);
1419 5391d806 bellard
                    break;
1420 5391d806 bellard
                case 0x2a:
1421 5391d806 bellard
                    cpu_to_ube16(&buf[0], 28 + 6);
1422 5391d806 bellard
                    buf[2] = 0x70;
1423 5391d806 bellard
                    buf[3] = 0;
1424 5391d806 bellard
                    buf[4] = 0;
1425 5391d806 bellard
                    buf[5] = 0;
1426 5391d806 bellard
                    buf[6] = 0;
1427 5391d806 bellard
                    buf[7] = 0;
1428 5391d806 bellard
1429 5391d806 bellard
                    buf[8] = 0x2a;
1430 5391d806 bellard
                    buf[9] = 0x12;
1431 0d4a05a1 ths
                    buf[10] = 0x00;
1432 5391d806 bellard
                    buf[11] = 0x00;
1433 3b46e624 ths
1434 5391d806 bellard
                    buf[12] = 0x70;
1435 5391d806 bellard
                    buf[13] = 3 << 5;
1436 5391d806 bellard
                    buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
1437 caed8802 bellard
                    if (bdrv_is_locked(s->bs))
1438 5391d806 bellard
                        buf[6] |= 1 << 1;
1439 5391d806 bellard
                    buf[15] = 0x00;
1440 5391d806 bellard
                    cpu_to_ube16(&buf[16], 706);
1441 5391d806 bellard
                    buf[18] = 0;
1442 5391d806 bellard
                    buf[19] = 2;
1443 5391d806 bellard
                    cpu_to_ube16(&buf[20], 512);
1444 5391d806 bellard
                    cpu_to_ube16(&buf[22], 706);
1445 5391d806 bellard
                    buf[24] = 0;
1446 5391d806 bellard
                    buf[25] = 0;
1447 5391d806 bellard
                    buf[26] = 0;
1448 5391d806 bellard
                    buf[27] = 0;
1449 5391d806 bellard
                    ide_atapi_cmd_reply(s, 28, max_len);
1450 5391d806 bellard
                    break;
1451 5391d806 bellard
                default:
1452 5391d806 bellard
                    goto error_cmd;
1453 5391d806 bellard
                }
1454 5391d806 bellard
                break;
1455 5391d806 bellard
            case 1: /* changeable values */
1456 5391d806 bellard
                goto error_cmd;
1457 5391d806 bellard
            case 2: /* default values */
1458 5391d806 bellard
                goto error_cmd;
1459 5391d806 bellard
            default:
1460 5391d806 bellard
            case 3: /* saved values */
1461 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1462 5391d806 bellard
                                    ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
1463 5391d806 bellard
                break;
1464 5391d806 bellard
            }
1465 5391d806 bellard
        }
1466 5391d806 bellard
        break;
1467 5391d806 bellard
    case GPCMD_REQUEST_SENSE:
1468 5391d806 bellard
        max_len = packet[4];
1469 5391d806 bellard
        memset(buf, 0, 18);
1470 5391d806 bellard
        buf[0] = 0x70 | (1 << 7);
1471 5391d806 bellard
        buf[2] = s->sense_key;
1472 5391d806 bellard
        buf[7] = 10;
1473 5391d806 bellard
        buf[12] = s->asc;
1474 5391d806 bellard
        ide_atapi_cmd_reply(s, 18, max_len);
1475 5391d806 bellard
        break;
1476 5391d806 bellard
    case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
1477 caed8802 bellard
        if (bdrv_is_inserted(s->bs)) {
1478 caed8802 bellard
            bdrv_set_locked(s->bs, packet[4] & 1);
1479 5391d806 bellard
            ide_atapi_cmd_ok(s);
1480 5391d806 bellard
        } else {
1481 5fafdf24 ths
            ide_atapi_cmd_error(s, SENSE_NOT_READY,
1482 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1483 5391d806 bellard
        }
1484 5391d806 bellard
        break;
1485 5391d806 bellard
    case GPCMD_READ_10:
1486 5391d806 bellard
    case GPCMD_READ_12:
1487 5391d806 bellard
        {
1488 5391d806 bellard
            int nb_sectors, lba;
1489 5391d806 bellard
1490 5391d806 bellard
            if (packet[0] == GPCMD_READ_10)
1491 5391d806 bellard
                nb_sectors = ube16_to_cpu(packet + 7);
1492 5391d806 bellard
            else
1493 5391d806 bellard
                nb_sectors = ube32_to_cpu(packet + 6);
1494 5391d806 bellard
            lba = ube32_to_cpu(packet + 2);
1495 5391d806 bellard
            if (nb_sectors == 0) {
1496 5391d806 bellard
                ide_atapi_cmd_ok(s);
1497 5391d806 bellard
                break;
1498 5391d806 bellard
            }
1499 98087450 bellard
            ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1500 98087450 bellard
        }
1501 98087450 bellard
        break;
1502 98087450 bellard
    case GPCMD_READ_CD:
1503 98087450 bellard
        {
1504 98087450 bellard
            int nb_sectors, lba, transfer_request;
1505 98087450 bellard
1506 98087450 bellard
            nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
1507 98087450 bellard
            lba = ube32_to_cpu(packet + 2);
1508 98087450 bellard
            if (nb_sectors == 0) {
1509 98087450 bellard
                ide_atapi_cmd_ok(s);
1510 98087450 bellard
                break;
1511 98087450 bellard
            }
1512 98087450 bellard
            transfer_request = packet[9];
1513 98087450 bellard
            switch(transfer_request & 0xf8) {
1514 98087450 bellard
            case 0x00:
1515 98087450 bellard
                /* nothing */
1516 98087450 bellard
                ide_atapi_cmd_ok(s);
1517 98087450 bellard
                break;
1518 98087450 bellard
            case 0x10:
1519 98087450 bellard
                /* normal read */
1520 98087450 bellard
                ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1521 98087450 bellard
                break;
1522 98087450 bellard
            case 0xf8:
1523 98087450 bellard
                /* read all data */
1524 98087450 bellard
                ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
1525 98087450 bellard
                break;
1526 98087450 bellard
            default:
1527 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1528 98087450 bellard
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1529 98087450 bellard
                break;
1530 98087450 bellard
            }
1531 5391d806 bellard
        }
1532 5391d806 bellard
        break;
1533 5391d806 bellard
    case GPCMD_SEEK:
1534 5391d806 bellard
        {
1535 96b8f136 ths
            unsigned int lba;
1536 96b8f136 ths
            uint64_t total_sectors;
1537 66c6ef76 bellard
1538 66c6ef76 bellard
            bdrv_get_geometry(s->bs, &total_sectors);
1539 66c6ef76 bellard
            total_sectors >>= 2;
1540 96b8f136 ths
            if (total_sectors == 0) {
1541 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_NOT_READY,
1542 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1543 5391d806 bellard
                break;
1544 5391d806 bellard
            }
1545 5391d806 bellard
            lba = ube32_to_cpu(packet + 2);
1546 66c6ef76 bellard
            if (lba >= total_sectors) {
1547 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1548 5391d806 bellard
                                    ASC_LOGICAL_BLOCK_OOR);
1549 5391d806 bellard
                break;
1550 5391d806 bellard
            }
1551 5391d806 bellard
            ide_atapi_cmd_ok(s);
1552 5391d806 bellard
        }
1553 5391d806 bellard
        break;
1554 5391d806 bellard
    case GPCMD_START_STOP_UNIT:
1555 5391d806 bellard
        {
1556 5391d806 bellard
            int start, eject;
1557 5391d806 bellard
            start = packet[4] & 1;
1558 5391d806 bellard
            eject = (packet[4] >> 1) & 1;
1559 3b46e624 ths
1560 caed8802 bellard
            if (eject && !start) {
1561 caed8802 bellard
                /* eject the disk */
1562 66c6ef76 bellard
                bdrv_eject(s->bs, 1);
1563 66c6ef76 bellard
            } else if (eject && start) {
1564 66c6ef76 bellard
                /* close the tray */
1565 66c6ef76 bellard
                bdrv_eject(s->bs, 0);
1566 caed8802 bellard
            }
1567 5391d806 bellard
            ide_atapi_cmd_ok(s);
1568 5391d806 bellard
        }
1569 5391d806 bellard
        break;
1570 5391d806 bellard
    case GPCMD_MECHANISM_STATUS:
1571 5391d806 bellard
        {
1572 5391d806 bellard
            max_len = ube16_to_cpu(packet + 8);
1573 5391d806 bellard
            cpu_to_ube16(buf, 0);
1574 5391d806 bellard
            /* no current LBA */
1575 5391d806 bellard
            buf[2] = 0;
1576 5391d806 bellard
            buf[3] = 0;
1577 5391d806 bellard
            buf[4] = 0;
1578 5391d806 bellard
            buf[5] = 1;
1579 5391d806 bellard
            cpu_to_ube16(buf + 6, 0);
1580 5391d806 bellard
            ide_atapi_cmd_reply(s, 8, max_len);
1581 5391d806 bellard
        }
1582 5391d806 bellard
        break;
1583 5391d806 bellard
    case GPCMD_READ_TOC_PMA_ATIP:
1584 5391d806 bellard
        {
1585 5391d806 bellard
            int format, msf, start_track, len;
1586 96b8f136 ths
            uint64_t total_sectors;
1587 5391d806 bellard
1588 66c6ef76 bellard
            bdrv_get_geometry(s->bs, &total_sectors);
1589 66c6ef76 bellard
            total_sectors >>= 2;
1590 96b8f136 ths
            if (total_sectors == 0) {
1591 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_NOT_READY,
1592 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1593 5391d806 bellard
                break;
1594 5391d806 bellard
            }
1595 5391d806 bellard
            max_len = ube16_to_cpu(packet + 7);
1596 5391d806 bellard
            format = packet[9] >> 6;
1597 5391d806 bellard
            msf = (packet[1] >> 1) & 1;
1598 5391d806 bellard
            start_track = packet[6];
1599 5391d806 bellard
            switch(format) {
1600 5391d806 bellard
            case 0:
1601 66c6ef76 bellard
                len = cdrom_read_toc(total_sectors, buf, msf, start_track);
1602 5391d806 bellard
                if (len < 0)
1603 5391d806 bellard
                    goto error_cmd;
1604 5391d806 bellard
                ide_atapi_cmd_reply(s, len, max_len);
1605 5391d806 bellard
                break;
1606 5391d806 bellard
            case 1:
1607 5391d806 bellard
                /* multi session : only a single session defined */
1608 5391d806 bellard
                memset(buf, 0, 12);
1609 5391d806 bellard
                buf[1] = 0x0a;
1610 5391d806 bellard
                buf[2] = 0x01;
1611 5391d806 bellard
                buf[3] = 0x01;
1612 5391d806 bellard
                ide_atapi_cmd_reply(s, 12, max_len);
1613 5391d806 bellard
                break;
1614 98087450 bellard
            case 2:
1615 66c6ef76 bellard
                len = cdrom_read_toc_raw(total_sectors, buf, msf, start_track);
1616 98087450 bellard
                if (len < 0)
1617 98087450 bellard
                    goto error_cmd;
1618 98087450 bellard
                ide_atapi_cmd_reply(s, len, max_len);
1619 98087450 bellard
                break;
1620 5391d806 bellard
            default:
1621 7f777bf3 bellard
            error_cmd:
1622 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1623 7f777bf3 bellard
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1624 7f777bf3 bellard
                break;
1625 5391d806 bellard
            }
1626 5391d806 bellard
        }
1627 5391d806 bellard
        break;
1628 5391d806 bellard
    case GPCMD_READ_CDVD_CAPACITY:
1629 66c6ef76 bellard
        {
1630 96b8f136 ths
            uint64_t total_sectors;
1631 66c6ef76 bellard
1632 66c6ef76 bellard
            bdrv_get_geometry(s->bs, &total_sectors);
1633 66c6ef76 bellard
            total_sectors >>= 2;
1634 96b8f136 ths
            if (total_sectors == 0) {
1635 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_NOT_READY,
1636 66c6ef76 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1637 66c6ef76 bellard
                break;
1638 66c6ef76 bellard
            }
1639 66c6ef76 bellard
            /* NOTE: it is really the number of sectors minus 1 */
1640 66c6ef76 bellard
            cpu_to_ube32(buf, total_sectors - 1);
1641 66c6ef76 bellard
            cpu_to_ube32(buf + 4, 2048);
1642 66c6ef76 bellard
            ide_atapi_cmd_reply(s, 8, 8);
1643 5391d806 bellard
        }
1644 5391d806 bellard
        break;
1645 d14049ea ths
    case GPCMD_READ_DVD_STRUCTURE:
1646 d14049ea ths
        {
1647 d14049ea ths
            int media = packet[1];
1648 d14049ea ths
            int layer = packet[6];
1649 d14049ea ths
            int format = packet[2];
1650 96b8f136 ths
            uint64_t total_sectors;
1651 d14049ea ths
1652 d14049ea ths
            if (media != 0 || layer != 0)
1653 d14049ea ths
            {
1654 d14049ea ths
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1655 d14049ea ths
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1656 d14049ea ths
            }
1657 d14049ea ths
1658 d14049ea ths
            switch (format) {
1659 d14049ea ths
                case 0:
1660 d14049ea ths
                    bdrv_get_geometry(s->bs, &total_sectors);
1661 d14049ea ths
                    total_sectors >>= 2;
1662 96b8f136 ths
                    if (total_sectors == 0) {
1663 96b8f136 ths
                        ide_atapi_cmd_error(s, SENSE_NOT_READY,
1664 96b8f136 ths
                                            ASC_MEDIUM_NOT_PRESENT);
1665 96b8f136 ths
                        break;
1666 96b8f136 ths
                    }
1667 d14049ea ths
1668 d14049ea ths
                    memset(buf, 0, 2052);
1669 d14049ea ths
1670 d14049ea ths
                    buf[4] = 1;   // DVD-ROM, part version 1
1671 d14049ea ths
                    buf[5] = 0xf; // 120mm disc, maximum rate unspecified
1672 d14049ea ths
                    buf[6] = 0;   // one layer, embossed data
1673 d14049ea ths
                    buf[7] = 0;
1674 d14049ea ths
1675 d14049ea ths
                    cpu_to_ube32(buf + 8, 0);
1676 d14049ea ths
                    cpu_to_ube32(buf + 12, total_sectors - 1);
1677 d14049ea ths
                    cpu_to_ube32(buf + 16, total_sectors - 1);
1678 d14049ea ths
1679 d14049ea ths
                    cpu_to_be16wu((uint16_t *)buf, 2048 + 4);
1680 d14049ea ths
1681 d14049ea ths
                    ide_atapi_cmd_reply(s, 2048 + 3, 2048 + 4);
1682 d14049ea ths
                    break;
1683 d14049ea ths
1684 d14049ea ths
                default:
1685 d14049ea ths
                    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1686 d14049ea ths
                                        ASC_INV_FIELD_IN_CMD_PACKET);
1687 d14049ea ths
                    break;
1688 d14049ea ths
            }
1689 d14049ea ths
        }
1690 d14049ea ths
        break;
1691 d14049ea ths
    case GPCMD_SET_SPEED:
1692 d14049ea ths
        ide_atapi_cmd_ok(s);
1693 d14049ea ths
        break;
1694 bd0d90b2 bellard
    case GPCMD_INQUIRY:
1695 bd0d90b2 bellard
        max_len = packet[4];
1696 bd0d90b2 bellard
        buf[0] = 0x05; /* CD-ROM */
1697 bd0d90b2 bellard
        buf[1] = 0x80; /* removable */
1698 bd0d90b2 bellard
        buf[2] = 0x00; /* ISO */
1699 bd0d90b2 bellard
        buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
1700 aa1f17c1 ths
        buf[4] = 31; /* additional length */
1701 bd0d90b2 bellard
        buf[5] = 0; /* reserved */
1702 bd0d90b2 bellard
        buf[6] = 0; /* reserved */
1703 bd0d90b2 bellard
        buf[7] = 0; /* reserved */
1704 bd0d90b2 bellard
        padstr8(buf + 8, 8, "QEMU");
1705 38cdea7c balrog
        padstr8(buf + 16, 16, "QEMU DVD-ROM");
1706 bd0d90b2 bellard
        padstr8(buf + 32, 4, QEMU_VERSION);
1707 bd0d90b2 bellard
        ide_atapi_cmd_reply(s, 36, max_len);
1708 bd0d90b2 bellard
        break;
1709 d14049ea ths
    case GPCMD_GET_CONFIGURATION:
1710 d14049ea ths
        {
1711 38cdea7c balrog
            uint32_t len;
1712 d14049ea ths
1713 d14049ea ths
            /* only feature 0 is supported */
1714 d14049ea ths
            if (packet[2] != 0 || packet[3] != 0) {
1715 d14049ea ths
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1716 d14049ea ths
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1717 d14049ea ths
                break;
1718 d14049ea ths
            }
1719 38cdea7c balrog
1720 38cdea7c balrog
            /* XXX: could result in alignment problems in some architectures */
1721 38cdea7c balrog
            max_len = ube16_to_cpu(packet + 7);
1722 38cdea7c balrog
            /*
1723 38cdea7c balrog
             * XXX: avoid overflow for io_buffer if max_len is bigger than the
1724 38cdea7c balrog
             *      size of that buffer (dimensioned to max number of sectors
1725 38cdea7c balrog
             *      to transfer at once)
1726 38cdea7c balrog
             *
1727 38cdea7c balrog
             *      Only a problem if the feature/profiles grow exponentially.
1728 38cdea7c balrog
             */
1729 38cdea7c balrog
            if (max_len > 512) /* XXX: assume 1 sector */
1730 38cdea7c balrog
                max_len = 512;
1731 38cdea7c balrog
1732 38cdea7c balrog
            memset(buf, 0, max_len);
1733 38cdea7c balrog
            /* 
1734 38cdea7c balrog
             * the number of sectors from the media tells us which profile
1735 38cdea7c balrog
             * to use as current.  0 means there is no media
1736 38cdea7c balrog
             *
1737 38cdea7c balrog
             * XXX: fails to detect correctly DVDs with less data burned
1738 38cdea7c balrog
             *      than what a CD can hold
1739 38cdea7c balrog
             */
1740 38cdea7c balrog
            if ((s -> nb_sectors)) {
1741 38cdea7c balrog
                if ((s -> nb_sectors > CD_MAX_SECTORS))
1742 38cdea7c balrog
                    cpu_to_ube16(buf + 6, MMC_PROFILE_DVD_ROM);
1743 38cdea7c balrog
                else
1744 38cdea7c balrog
                    cpu_to_ube16(buf + 6, MMC_PROFILE_CD_ROM);
1745 38cdea7c balrog
            }
1746 38cdea7c balrog
1747 38cdea7c balrog
            len = 8; /* header completed */
1748 38cdea7c balrog
            if (max_len > len) {
1749 38cdea7c balrog
                uint8_t index = 0;
1750 38cdea7c balrog
1751 38cdea7c balrog
                buf[10] = 0x02 | 0x01; /* persistent and current */
1752 38cdea7c balrog
                len += 4; /* header */
1753 38cdea7c balrog
                len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_DVD_ROM);
1754 38cdea7c balrog
                len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_CD_ROM);
1755 38cdea7c balrog
            }
1756 38cdea7c balrog
            cpu_to_ube32(buf, len - 4); /* data length */
1757 38cdea7c balrog
1758 38cdea7c balrog
            ide_atapi_cmd_reply(s, len, max_len);
1759 d14049ea ths
            break;
1760 d14049ea ths
        }
1761 5391d806 bellard
    default:
1762 5fafdf24 ths
        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1763 7f777bf3 bellard
                            ASC_ILLEGAL_OPCODE);
1764 5391d806 bellard
        break;
1765 5391d806 bellard
    }
1766 5391d806 bellard
}
1767 5391d806 bellard
1768 201a51fc balrog
static void ide_cfata_metadata_inquiry(IDEState *s)
1769 201a51fc balrog
{
1770 201a51fc balrog
    uint16_t *p;
1771 201a51fc balrog
    uint32_t spd;
1772 201a51fc balrog
1773 201a51fc balrog
    p = (uint16_t *) s->io_buffer;
1774 201a51fc balrog
    memset(p, 0, 0x200);
1775 201a51fc balrog
    spd = ((s->mdata_size - 1) >> 9) + 1;
1776 201a51fc balrog
1777 201a51fc balrog
    put_le16(p + 0, 0x0001);                        /* Data format revision */
1778 201a51fc balrog
    put_le16(p + 1, 0x0000);                        /* Media property: silicon */
1779 201a51fc balrog
    put_le16(p + 2, s->media_changed);                /* Media status */
1780 201a51fc balrog
    put_le16(p + 3, s->mdata_size & 0xffff);        /* Capacity in bytes (low) */
1781 201a51fc balrog
    put_le16(p + 4, s->mdata_size >> 16);        /* Capacity in bytes (high) */
1782 201a51fc balrog
    put_le16(p + 5, spd & 0xffff);                /* Sectors per device (low) */
1783 201a51fc balrog
    put_le16(p + 6, spd >> 16);                        /* Sectors per device (high) */
1784 201a51fc balrog
}
1785 201a51fc balrog
1786 201a51fc balrog
static void ide_cfata_metadata_read(IDEState *s)
1787 201a51fc balrog
{
1788 201a51fc balrog
    uint16_t *p;
1789 201a51fc balrog
1790 201a51fc balrog
    if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) {
1791 201a51fc balrog
        s->status = ERR_STAT;
1792 201a51fc balrog
        s->error = ABRT_ERR;
1793 201a51fc balrog
        return;
1794 201a51fc balrog
    }
1795 201a51fc balrog
1796 201a51fc balrog
    p = (uint16_t *) s->io_buffer;
1797 201a51fc balrog
    memset(p, 0, 0x200);
1798 201a51fc balrog
1799 201a51fc balrog
    put_le16(p + 0, s->media_changed);                /* Media status */
1800 201a51fc balrog
    memcpy(p + 1, s->mdata_storage + (((s->hcyl << 16) | s->lcyl) << 9),
1801 201a51fc balrog
                    MIN(MIN(s->mdata_size - (((s->hcyl << 16) | s->lcyl) << 9),
1802 201a51fc balrog
                                    s->nsector << 9), 0x200 - 2));
1803 201a51fc balrog
}
1804 201a51fc balrog
1805 201a51fc balrog
static void ide_cfata_metadata_write(IDEState *s)
1806 201a51fc balrog
{
1807 201a51fc balrog
    if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) {
1808 201a51fc balrog
        s->status = ERR_STAT;
1809 201a51fc balrog
        s->error = ABRT_ERR;
1810 201a51fc balrog
        return;
1811 201a51fc balrog
    }
1812 201a51fc balrog
1813 201a51fc balrog
    s->media_changed = 0;
1814 201a51fc balrog
1815 201a51fc balrog
    memcpy(s->mdata_storage + (((s->hcyl << 16) | s->lcyl) << 9),
1816 201a51fc balrog
                    s->io_buffer + 2,
1817 201a51fc balrog
                    MIN(MIN(s->mdata_size - (((s->hcyl << 16) | s->lcyl) << 9),
1818 201a51fc balrog
                                    s->nsector << 9), 0x200 - 2));
1819 201a51fc balrog
}
1820 201a51fc balrog
1821 bd491d6a ths
/* called when the inserted state of the media has changed */
1822 bd491d6a ths
static void cdrom_change_cb(void *opaque)
1823 bd491d6a ths
{
1824 bd491d6a ths
    IDEState *s = opaque;
1825 96b8f136 ths
    uint64_t nb_sectors;
1826 bd491d6a ths
1827 bd491d6a ths
    /* XXX: send interrupt too */
1828 bd491d6a ths
    bdrv_get_geometry(s->bs, &nb_sectors);
1829 bd491d6a ths
    s->nb_sectors = nb_sectors;
1830 bd491d6a ths
}
1831 bd491d6a ths
1832 c2ff060f bellard
static void ide_cmd_lba48_transform(IDEState *s, int lba48)
1833 c2ff060f bellard
{
1834 c2ff060f bellard
    s->lba48 = lba48;
1835 c2ff060f bellard
1836 c2ff060f bellard
    /* handle the 'magic' 0 nsector count conversion here. to avoid
1837 c2ff060f bellard
     * fiddling with the rest of the read logic, we just store the
1838 c2ff060f bellard
     * full sector count in ->nsector and ignore ->hob_nsector from now
1839 c2ff060f bellard
     */
1840 c2ff060f bellard
    if (!s->lba48) {
1841 c2ff060f bellard
        if (!s->nsector)
1842 c2ff060f bellard
            s->nsector = 256;
1843 c2ff060f bellard
    } else {
1844 c2ff060f bellard
        if (!s->nsector && !s->hob_nsector)
1845 c2ff060f bellard
            s->nsector = 65536;
1846 c2ff060f bellard
        else {
1847 c2ff060f bellard
            int lo = s->nsector;
1848 c2ff060f bellard
            int hi = s->hob_nsector;
1849 c2ff060f bellard
1850 c2ff060f bellard
            s->nsector = (hi << 8) | lo;
1851 c2ff060f bellard
        }
1852 c2ff060f bellard
    }
1853 c2ff060f bellard
}
1854 c2ff060f bellard
1855 c2ff060f bellard
static void ide_clear_hob(IDEState *ide_if)
1856 c2ff060f bellard
{
1857 c2ff060f bellard
    /* any write clears HOB high bit of device control register */
1858 c2ff060f bellard
    ide_if[0].select &= ~(1 << 7);
1859 c2ff060f bellard
    ide_if[1].select &= ~(1 << 7);
1860 c2ff060f bellard
}
1861 c2ff060f bellard
1862 caed8802 bellard
static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1863 caed8802 bellard
{
1864 caed8802 bellard
    IDEState *ide_if = opaque;
1865 c45c3d00 bellard
    IDEState *s;
1866 5391d806 bellard
    int unit, n;
1867 c2ff060f bellard
    int lba48 = 0;
1868 5391d806 bellard
1869 5391d806 bellard
#ifdef DEBUG_IDE
1870 5391d806 bellard
    printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);
1871 5391d806 bellard
#endif
1872 c2ff060f bellard
1873 5391d806 bellard
    addr &= 7;
1874 5391d806 bellard
    switch(addr) {
1875 5391d806 bellard
    case 0:
1876 5391d806 bellard
        break;
1877 5391d806 bellard
    case 1:
1878 c2ff060f bellard
        ide_clear_hob(ide_if);
1879 c45c3d00 bellard
        /* NOTE: data is written to the two drives */
1880 c2ff060f bellard
        ide_if[0].hob_feature = ide_if[0].feature;
1881 c2ff060f bellard
        ide_if[1].hob_feature = ide_if[1].feature;
1882 c45c3d00 bellard
        ide_if[0].feature = val;
1883 c45c3d00 bellard
        ide_if[1].feature = val;
1884 5391d806 bellard
        break;
1885 5391d806 bellard
    case 2:
1886 c2ff060f bellard
        ide_clear_hob(ide_if);
1887 c2ff060f bellard
        ide_if[0].hob_nsector = ide_if[0].nsector;
1888 c2ff060f bellard
        ide_if[1].hob_nsector = ide_if[1].nsector;
1889 c45c3d00 bellard
        ide_if[0].nsector = val;
1890 c45c3d00 bellard
        ide_if[1].nsector = val;
1891 5391d806 bellard
        break;
1892 5391d806 bellard
    case 3:
1893 c2ff060f bellard
        ide_clear_hob(ide_if);
1894 c2ff060f bellard
        ide_if[0].hob_sector = ide_if[0].sector;
1895 c2ff060f bellard
        ide_if[1].hob_sector = ide_if[1].sector;
1896 c45c3d00 bellard
        ide_if[0].sector = val;
1897 c45c3d00 bellard
        ide_if[1].sector = val;
1898 5391d806 bellard
        break;
1899 5391d806 bellard
    case 4:
1900 c2ff060f bellard
        ide_clear_hob(ide_if);
1901 c2ff060f bellard
        ide_if[0].hob_lcyl = ide_if[0].lcyl;
1902 c2ff060f bellard
        ide_if[1].hob_lcyl = ide_if[1].lcyl;
1903 c45c3d00 bellard
        ide_if[0].lcyl = val;
1904 c45c3d00 bellard
        ide_if[1].lcyl = val;
1905 5391d806 bellard
        break;
1906 5391d806 bellard
    case 5:
1907 c2ff060f bellard
        ide_clear_hob(ide_if);
1908 c2ff060f bellard
        ide_if[0].hob_hcyl = ide_if[0].hcyl;
1909 c2ff060f bellard
        ide_if[1].hob_hcyl = ide_if[1].hcyl;
1910 c45c3d00 bellard
        ide_if[0].hcyl = val;
1911 c45c3d00 bellard
        ide_if[1].hcyl = val;
1912 5391d806 bellard
        break;
1913 5391d806 bellard
    case 6:
1914 c2ff060f bellard
        /* FIXME: HOB readback uses bit 7 */
1915 7ae98627 bellard
        ide_if[0].select = (val & ~0x10) | 0xa0;
1916 7ae98627 bellard
        ide_if[1].select = (val | 0x10) | 0xa0;
1917 5391d806 bellard
        /* select drive */
1918 5391d806 bellard
        unit = (val >> 4) & 1;
1919 5391d806 bellard
        s = ide_if + unit;
1920 5391d806 bellard
        ide_if->cur_drive = s;
1921 5391d806 bellard
        break;
1922 5391d806 bellard
    default:
1923 5391d806 bellard
    case 7:
1924 5391d806 bellard
        /* command */
1925 5391d806 bellard
#if defined(DEBUG_IDE)
1926 5391d806 bellard
        printf("ide: CMD=%02x\n", val);
1927 5391d806 bellard
#endif
1928 c45c3d00 bellard
        s = ide_if->cur_drive;
1929 66201e2d bellard
        /* ignore commands to non existant slave */
1930 5fafdf24 ths
        if (s != ide_if && !s->bs)
1931 66201e2d bellard
            break;
1932 c2ff060f bellard
1933 5391d806 bellard
        switch(val) {
1934 5391d806 bellard
        case WIN_IDENTIFY:
1935 5391d806 bellard
            if (s->bs && !s->is_cdrom) {
1936 201a51fc balrog
                if (!s->is_cf)
1937 201a51fc balrog
                    ide_identify(s);
1938 201a51fc balrog
                else
1939 201a51fc balrog
                    ide_cfata_identify(s);
1940 2a282056 bellard
                s->status = READY_STAT | SEEK_STAT;
1941 5391d806 bellard
                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1942 5391d806 bellard
            } else {
1943 5391d806 bellard
                if (s->is_cdrom) {
1944 5391d806 bellard
                    ide_set_signature(s);
1945 5391d806 bellard
                }
1946 5391d806 bellard
                ide_abort_command(s);
1947 5391d806 bellard
            }
1948 5391d806 bellard
            ide_set_irq(s);
1949 5391d806 bellard
            break;
1950 5391d806 bellard
        case WIN_SPECIFY:
1951 5391d806 bellard
        case WIN_RECAL:
1952 a136e5a8 bellard
            s->error = 0;
1953 769bec72 bellard
            s->status = READY_STAT | SEEK_STAT;
1954 5391d806 bellard
            ide_set_irq(s);
1955 5391d806 bellard
            break;
1956 5391d806 bellard
        case WIN_SETMULT:
1957 201a51fc balrog
            if (s->is_cf && s->nsector == 0) {
1958 201a51fc balrog
                /* Disable Read and Write Multiple */
1959 201a51fc balrog
                s->mult_sectors = 0;
1960 201a51fc balrog
                s->status = READY_STAT;
1961 201a51fc balrog
            } else if ((s->nsector & 0xff) != 0 &&
1962 39dfc926 ths
                ((s->nsector & 0xff) > MAX_MULT_SECTORS ||
1963 39dfc926 ths
                 (s->nsector & (s->nsector - 1)) != 0)) {
1964 5391d806 bellard
                ide_abort_command(s);
1965 5391d806 bellard
            } else {
1966 292eef5a ths
                s->mult_sectors = s->nsector & 0xff;
1967 5391d806 bellard
                s->status = READY_STAT;
1968 5391d806 bellard
            }
1969 5391d806 bellard
            ide_set_irq(s);
1970 5391d806 bellard
            break;
1971 c2ff060f bellard
        case WIN_VERIFY_EXT:
1972 c2ff060f bellard
            lba48 = 1;
1973 4ce900b4 bellard
        case WIN_VERIFY:
1974 4ce900b4 bellard
        case WIN_VERIFY_ONCE:
1975 4ce900b4 bellard
            /* do sector number check ? */
1976 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1977 4ce900b4 bellard
            s->status = READY_STAT;
1978 4ce900b4 bellard
            ide_set_irq(s);
1979 4ce900b4 bellard
            break;
1980 c2ff060f bellard
        case WIN_READ_EXT:
1981 c2ff060f bellard
            lba48 = 1;
1982 5391d806 bellard
        case WIN_READ:
1983 5391d806 bellard
        case WIN_READ_ONCE:
1984 5fafdf24 ths
            if (!s->bs)
1985 6b136f9e bellard
                goto abort_cmd;
1986 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1987 5391d806 bellard
            s->req_nb_sectors = 1;
1988 5391d806 bellard
            ide_sector_read(s);
1989 5391d806 bellard
            break;
1990 c2ff060f bellard
        case WIN_WRITE_EXT:
1991 c2ff060f bellard
            lba48 = 1;
1992 5391d806 bellard
        case WIN_WRITE:
1993 5391d806 bellard
        case WIN_WRITE_ONCE:
1994 201a51fc balrog
        case CFA_WRITE_SECT_WO_ERASE:
1995 201a51fc balrog
        case WIN_WRITE_VERIFY:
1996 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1997 a136e5a8 bellard
            s->error = 0;
1998 f66723fa bellard
            s->status = SEEK_STAT | READY_STAT;
1999 5391d806 bellard
            s->req_nb_sectors = 1;
2000 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
2001 201a51fc balrog
            s->media_changed = 1;
2002 5391d806 bellard
            break;
2003 c2ff060f bellard
        case WIN_MULTREAD_EXT:
2004 c2ff060f bellard
            lba48 = 1;
2005 5391d806 bellard
        case WIN_MULTREAD:
2006 5391d806 bellard
            if (!s->mult_sectors)
2007 5391d806 bellard
                goto abort_cmd;
2008 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
2009 5391d806 bellard
            s->req_nb_sectors = s->mult_sectors;
2010 5391d806 bellard
            ide_sector_read(s);
2011 5391d806 bellard
            break;
2012 c2ff060f bellard
        case WIN_MULTWRITE_EXT:
2013 c2ff060f bellard
            lba48 = 1;
2014 5391d806 bellard
        case WIN_MULTWRITE:
2015 201a51fc balrog
        case CFA_WRITE_MULTI_WO_ERASE:
2016 5391d806 bellard
            if (!s->mult_sectors)
2017 5391d806 bellard
                goto abort_cmd;
2018 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
2019 a136e5a8 bellard
            s->error = 0;
2020 f66723fa bellard
            s->status = SEEK_STAT | READY_STAT;
2021 5391d806 bellard
            s->req_nb_sectors = s->mult_sectors;
2022 5391d806 bellard
            n = s->nsector;
2023 5391d806 bellard
            if (n > s->req_nb_sectors)
2024 5391d806 bellard
                n = s->req_nb_sectors;
2025 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
2026 201a51fc balrog
            s->media_changed = 1;
2027 5391d806 bellard
            break;
2028 c2ff060f bellard
        case WIN_READDMA_EXT:
2029 c2ff060f bellard
            lba48 = 1;
2030 98087450 bellard
        case WIN_READDMA:
2031 98087450 bellard
        case WIN_READDMA_ONCE:
2032 5fafdf24 ths
            if (!s->bs)
2033 98087450 bellard
                goto abort_cmd;
2034 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
2035 98087450 bellard
            ide_sector_read_dma(s);
2036 98087450 bellard
            break;
2037 c2ff060f bellard
        case WIN_WRITEDMA_EXT:
2038 c2ff060f bellard
            lba48 = 1;
2039 98087450 bellard
        case WIN_WRITEDMA:
2040 98087450 bellard
        case WIN_WRITEDMA_ONCE:
2041 5fafdf24 ths
            if (!s->bs)
2042 98087450 bellard
                goto abort_cmd;
2043 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
2044 98087450 bellard
            ide_sector_write_dma(s);
2045 201a51fc balrog
            s->media_changed = 1;
2046 98087450 bellard
            break;
2047 c2ff060f bellard
        case WIN_READ_NATIVE_MAX_EXT:
2048 c2ff060f bellard
            lba48 = 1;
2049 5391d806 bellard
        case WIN_READ_NATIVE_MAX:
2050 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
2051 5391d806 bellard
            ide_set_sector(s, s->nb_sectors - 1);
2052 5391d806 bellard
            s->status = READY_STAT;
2053 5391d806 bellard
            ide_set_irq(s);
2054 5391d806 bellard
            break;
2055 a136e5a8 bellard
        case WIN_CHECKPOWERMODE1:
2056 201a51fc balrog
        case WIN_CHECKPOWERMODE2:
2057 a136e5a8 bellard
            s->nsector = 0xff; /* device active or idle */
2058 a136e5a8 bellard
            s->status = READY_STAT;
2059 a136e5a8 bellard
            ide_set_irq(s);
2060 a136e5a8 bellard
            break;
2061 34e538ae bellard
        case WIN_SETFEATURES:
2062 34e538ae bellard
            if (!s->bs)
2063 34e538ae bellard
                goto abort_cmd;
2064 34e538ae bellard
            /* XXX: valid for CDROM ? */
2065 34e538ae bellard
            switch(s->feature) {
2066 e1f63470 ths
            case 0xcc: /* reverting to power-on defaults enable */
2067 e1f63470 ths
            case 0x66: /* reverting to power-on defaults disable */
2068 34e538ae bellard
            case 0x02: /* write cache enable */
2069 34e538ae bellard
            case 0x82: /* write cache disable */
2070 34e538ae bellard
            case 0xaa: /* read look-ahead enable */
2071 34e538ae bellard
            case 0x55: /* read look-ahead disable */
2072 201a51fc balrog
            case 0x05: /* set advanced power management mode */
2073 201a51fc balrog
            case 0x85: /* disable advanced power management mode */
2074 201a51fc balrog
            case 0x69: /* NOP */
2075 201a51fc balrog
            case 0x67: /* NOP */
2076 201a51fc balrog
            case 0x96: /* NOP */
2077 201a51fc balrog
            case 0x9a: /* NOP */
2078 c3e88d8c ths
            case 0x42: /* enable Automatic Acoustic Mode */
2079 c3e88d8c ths
            case 0xc2: /* disable Automatic Acoustic Mode */
2080 e0fe67aa bellard
                s->status = READY_STAT | SEEK_STAT;
2081 34e538ae bellard
                ide_set_irq(s);
2082 34e538ae bellard
                break;
2083 94458802 bellard
            case 0x03: { /* set transfer mode */
2084 94458802 bellard
                uint8_t val = s->nsector & 0x07;
2085 94458802 bellard
2086 94458802 bellard
                switch (s->nsector >> 3) {
2087 94458802 bellard
                    case 0x00: /* pio default */
2088 94458802 bellard
                    case 0x01: /* pio mode */
2089 94458802 bellard
                        put_le16(s->identify_data + 63,0x07);
2090 94458802 bellard
                        put_le16(s->identify_data + 88,0x3f);
2091 94458802 bellard
                        break;
2092 94458802 bellard
                    case 0x04: /* mdma mode */
2093 94458802 bellard
                        put_le16(s->identify_data + 63,0x07 | (1 << (val + 8)));
2094 94458802 bellard
                        put_le16(s->identify_data + 88,0x3f);
2095 94458802 bellard
                        break;
2096 94458802 bellard
                    case 0x08: /* udma mode */
2097 94458802 bellard
                        put_le16(s->identify_data + 63,0x07);
2098 94458802 bellard
                        put_le16(s->identify_data + 88,0x3f | (1 << (val + 8)));
2099 94458802 bellard
                        break;
2100 94458802 bellard
                    default:
2101 94458802 bellard
                        goto abort_cmd;
2102 94458802 bellard
                }
2103 94458802 bellard
                s->status = READY_STAT | SEEK_STAT;
2104 94458802 bellard
                ide_set_irq(s);
2105 94458802 bellard
                break;
2106 94458802 bellard
            }
2107 34e538ae bellard
            default:
2108 34e538ae bellard
                goto abort_cmd;
2109 34e538ae bellard
            }
2110 34e538ae bellard
            break;
2111 c2ff060f bellard
        case WIN_FLUSH_CACHE:
2112 c2ff060f bellard
        case WIN_FLUSH_CACHE_EXT:
2113 7a6cba61 pbrook
            if (s->bs)
2114 7a6cba61 pbrook
                bdrv_flush(s->bs);
2115 7a6cba61 pbrook
            s->status = READY_STAT;
2116 7a6cba61 pbrook
            ide_set_irq(s);
2117 7a6cba61 pbrook
            break;
2118 c3e88d8c ths
        case WIN_STANDBY:
2119 c3e88d8c ths
        case WIN_STANDBY2:
2120 c3e88d8c ths
        case WIN_STANDBYNOW1:
2121 201a51fc balrog
        case WIN_STANDBYNOW2:
2122 c451ee71 bellard
        case WIN_IDLEIMMEDIATE:
2123 201a51fc balrog
        case CFA_IDLEIMMEDIATE:
2124 201a51fc balrog
        case WIN_SETIDLE1:
2125 201a51fc balrog
        case WIN_SETIDLE2:
2126 c3e88d8c ths
        case WIN_SLEEPNOW1:
2127 c3e88d8c ths
        case WIN_SLEEPNOW2:
2128 c3e88d8c ths
            s->status = READY_STAT;
2129 a7dfe172 bellard
            ide_set_irq(s);
2130 a7dfe172 bellard
            break;
2131 5391d806 bellard
            /* ATAPI commands */
2132 5391d806 bellard
        case WIN_PIDENTIFY:
2133 5391d806 bellard
            if (s->is_cdrom) {
2134 5391d806 bellard
                ide_atapi_identify(s);
2135 1298fe63 bellard
                s->status = READY_STAT | SEEK_STAT;
2136 5391d806 bellard
                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
2137 5391d806 bellard
            } else {
2138 5391d806 bellard
                ide_abort_command(s);
2139 5391d806 bellard
            }
2140 5391d806 bellard
            ide_set_irq(s);
2141 5391d806 bellard
            break;
2142 c451ee71 bellard
        case WIN_DIAGNOSE:
2143 c451ee71 bellard
            ide_set_signature(s);
2144 38453b93 balrog
            s->status = READY_STAT;
2145 c451ee71 bellard
            s->error = 0x01;
2146 f5fdd0a8 balrog
            ide_set_irq(s);
2147 c451ee71 bellard
            break;
2148 5391d806 bellard
        case WIN_SRST:
2149 5391d806 bellard
            if (!s->is_cdrom)
2150 5391d806 bellard
                goto abort_cmd;
2151 5391d806 bellard
            ide_set_signature(s);
2152 6b136f9e bellard
            s->status = 0x00; /* NOTE: READY is _not_ set */
2153 5391d806 bellard
            s->error = 0x01;
2154 5391d806 bellard
            break;
2155 5391d806 bellard
        case WIN_PACKETCMD:
2156 5391d806 bellard
            if (!s->is_cdrom)
2157 5391d806 bellard
                goto abort_cmd;
2158 98087450 bellard
            /* overlapping commands not supported */
2159 98087450 bellard
            if (s->feature & 0x02)
2160 5391d806 bellard
                goto abort_cmd;
2161 7603d156 ths
            s->status = READY_STAT;
2162 98087450 bellard
            s->atapi_dma = s->feature & 1;
2163 5391d806 bellard
            s->nsector = 1;
2164 5fafdf24 ths
            ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
2165 5391d806 bellard
                               ide_atapi_cmd);
2166 5391d806 bellard
            break;
2167 201a51fc balrog
        /* CF-ATA commands */
2168 201a51fc balrog
        case CFA_REQ_EXT_ERROR_CODE:
2169 201a51fc balrog
            if (!s->is_cf)
2170 201a51fc balrog
                goto abort_cmd;
2171 201a51fc balrog
            s->error = 0x09;    /* miscellaneous error */
2172 201a51fc balrog
            s->status = READY_STAT;
2173 201a51fc balrog
            ide_set_irq(s);
2174 201a51fc balrog
            break;
2175 201a51fc balrog
        case CFA_ERASE_SECTORS:
2176 201a51fc balrog
        case CFA_WEAR_LEVEL:
2177 201a51fc balrog
            if (!s->is_cf)
2178 201a51fc balrog
                goto abort_cmd;
2179 201a51fc balrog
            if (val == CFA_WEAR_LEVEL)
2180 201a51fc balrog
                s->nsector = 0;
2181 201a51fc balrog
            if (val == CFA_ERASE_SECTORS)
2182 201a51fc balrog
                s->media_changed = 1;
2183 201a51fc balrog
            s->error = 0x00;
2184 201a51fc balrog
            s->status = READY_STAT;
2185 201a51fc balrog
            ide_set_irq(s);
2186 201a51fc balrog
            break;
2187 201a51fc balrog
        case CFA_TRANSLATE_SECTOR:
2188 201a51fc balrog
            if (!s->is_cf)
2189 201a51fc balrog
                goto abort_cmd;
2190 201a51fc balrog
            s->error = 0x00;
2191 201a51fc balrog
            s->status = READY_STAT;
2192 201a51fc balrog
            memset(s->io_buffer, 0, 0x200);
2193 201a51fc balrog
            s->io_buffer[0x00] = s->hcyl;                        /* Cyl MSB */
2194 201a51fc balrog
            s->io_buffer[0x01] = s->lcyl;                        /* Cyl LSB */
2195 201a51fc balrog
            s->io_buffer[0x02] = s->select;                        /* Head */
2196 201a51fc balrog
            s->io_buffer[0x03] = s->sector;                        /* Sector */
2197 201a51fc balrog
            s->io_buffer[0x04] = ide_get_sector(s) >> 16;        /* LBA MSB */
2198 201a51fc balrog
            s->io_buffer[0x05] = ide_get_sector(s) >> 8;        /* LBA */
2199 201a51fc balrog
            s->io_buffer[0x06] = ide_get_sector(s) >> 0;        /* LBA LSB */
2200 201a51fc balrog
            s->io_buffer[0x13] = 0x00;                                /* Erase flag */
2201 201a51fc balrog
            s->io_buffer[0x18] = 0x00;                                /* Hot count */
2202 201a51fc balrog
            s->io_buffer[0x19] = 0x00;                                /* Hot count */
2203 201a51fc balrog
            s->io_buffer[0x1a] = 0x01;                                /* Hot count */
2204 201a51fc balrog
            ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
2205 201a51fc balrog
            ide_set_irq(s);
2206 201a51fc balrog
            break;
2207 201a51fc balrog
        case CFA_ACCESS_METADATA_STORAGE:
2208 201a51fc balrog
            if (!s->is_cf)
2209 201a51fc balrog
                goto abort_cmd;
2210 201a51fc balrog
            switch (s->feature) {
2211 201a51fc balrog
            case 0x02:        /* Inquiry Metadata Storage */
2212 201a51fc balrog
                ide_cfata_metadata_inquiry(s);
2213 201a51fc balrog
                break;
2214 201a51fc balrog
            case 0x03:        /* Read Metadata Storage */
2215 201a51fc balrog
                ide_cfata_metadata_read(s);
2216 201a51fc balrog
                break;
2217 201a51fc balrog
            case 0x04:        /* Write Metadata Storage */
2218 201a51fc balrog
                ide_cfata_metadata_write(s);
2219 201a51fc balrog
                break;
2220 201a51fc balrog
            default:
2221 201a51fc balrog
                goto abort_cmd;
2222 201a51fc balrog
            }
2223 201a51fc balrog
            ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
2224 201a51fc balrog
            s->status = 0x00; /* NOTE: READY is _not_ set */
2225 201a51fc balrog
            ide_set_irq(s);
2226 201a51fc balrog
            break;
2227 201a51fc balrog
        case IBM_SENSE_CONDITION:
2228 201a51fc balrog
            if (!s->is_cf)
2229 201a51fc balrog
                goto abort_cmd;
2230 201a51fc balrog
            switch (s->feature) {
2231 201a51fc balrog
            case 0x01:  /* sense temperature in device */
2232 201a51fc balrog
                s->nsector = 0x50;      /* +20 C */
2233 201a51fc balrog
                break;
2234 201a51fc balrog
            default:
2235 201a51fc balrog
                goto abort_cmd;
2236 201a51fc balrog
            }
2237 201a51fc balrog
            s->status = READY_STAT;
2238 201a51fc balrog
            ide_set_irq(s);
2239 201a51fc balrog
            break;
2240 5391d806 bellard
        default:
2241 5391d806 bellard
        abort_cmd:
2242 5391d806 bellard
            ide_abort_command(s);
2243 5391d806 bellard
            ide_set_irq(s);
2244 5391d806 bellard
            break;
2245 5391d806 bellard
        }
2246 5391d806 bellard
    }
2247 5391d806 bellard
}
2248 5391d806 bellard
2249 caed8802 bellard
static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
2250 5391d806 bellard
{
2251 7ae98627 bellard
    IDEState *ide_if = opaque;
2252 7ae98627 bellard
    IDEState *s = ide_if->cur_drive;
2253 5391d806 bellard
    uint32_t addr;
2254 c2ff060f bellard
    int ret, hob;
2255 5391d806 bellard
2256 5391d806 bellard
    addr = addr1 & 7;
2257 c2ff060f bellard
    /* FIXME: HOB readback uses bit 7, but it's always set right now */
2258 c2ff060f bellard
    //hob = s->select & (1 << 7);
2259 c2ff060f bellard
    hob = 0;
2260 5391d806 bellard
    switch(addr) {
2261 5391d806 bellard
    case 0:
2262 5391d806 bellard
        ret = 0xff;
2263 5391d806 bellard
        break;
2264 5391d806 bellard
    case 1:
2265 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
2266 c45c3d00 bellard
            ret = 0;
2267 c2ff060f bellard
        else if (!hob)
2268 c45c3d00 bellard
            ret = s->error;
2269 c2ff060f bellard
        else
2270 c2ff060f bellard
            ret = s->hob_feature;
2271 5391d806 bellard
        break;
2272 5391d806 bellard
    case 2:
2273 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
2274 c45c3d00 bellard
            ret = 0;
2275 c2ff060f bellard
        else if (!hob)
2276 c45c3d00 bellard
            ret = s->nsector & 0xff;
2277 c2ff060f bellard
        else
2278 c2ff060f bellard
            ret = s->hob_nsector;
2279 5391d806 bellard
        break;
2280 5391d806 bellard
    case 3:
2281 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
2282 c45c3d00 bellard
            ret = 0;
2283 c2ff060f bellard
        else if (!hob)
2284 c45c3d00 bellard
            ret = s->sector;
2285 c2ff060f bellard
        else
2286 c2ff060f bellard
            ret = s->hob_sector;
2287 5391d806 bellard
        break;
2288 5391d806 bellard
    case 4:
2289 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
2290 c45c3d00 bellard
            ret = 0;
2291 c2ff060f bellard
        else if (!hob)
2292 c45c3d00 bellard
            ret = s->lcyl;
2293 c2ff060f bellard
        else
2294 c2ff060f bellard
            ret = s->hob_lcyl;
2295 5391d806 bellard
        break;
2296 5391d806 bellard
    case 5:
2297 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
2298 c45c3d00 bellard
            ret = 0;
2299 c2ff060f bellard
        else if (!hob)
2300 c45c3d00 bellard
            ret = s->hcyl;
2301 c2ff060f bellard
        else
2302 c2ff060f bellard
            ret = s->hob_hcyl;
2303 5391d806 bellard
        break;
2304 5391d806 bellard
    case 6:
2305 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
2306 c45c3d00 bellard
            ret = 0;
2307 c45c3d00 bellard
        else
2308 7ae98627 bellard
            ret = s->select;
2309 5391d806 bellard
        break;
2310 5391d806 bellard
    default:
2311 5391d806 bellard
    case 7:
2312 66201e2d bellard
        if ((!ide_if[0].bs && !ide_if[1].bs) ||
2313 66201e2d bellard
            (s != ide_if && !s->bs))
2314 c45c3d00 bellard
            ret = 0;
2315 c45c3d00 bellard
        else
2316 c45c3d00 bellard
            ret = s->status;
2317 d537cf6c pbrook
        qemu_irq_lower(s->irq);
2318 5391d806 bellard
        break;
2319 5391d806 bellard
    }
2320 5391d806 bellard
#ifdef DEBUG_IDE
2321 5391d806 bellard
    printf("ide: read addr=0x%x val=%02x\n", addr1, ret);
2322 5391d806 bellard
#endif
2323 5391d806 bellard
    return ret;
2324 5391d806 bellard
}
2325 5391d806 bellard
2326 caed8802 bellard
static uint32_t ide_status_read(void *opaque, uint32_t addr)
2327 5391d806 bellard
{
2328 7ae98627 bellard
    IDEState *ide_if = opaque;
2329 7ae98627 bellard
    IDEState *s = ide_if->cur_drive;
2330 5391d806 bellard
    int ret;
2331 7ae98627 bellard
2332 66201e2d bellard
    if ((!ide_if[0].bs && !ide_if[1].bs) ||
2333 66201e2d bellard
        (s != ide_if && !s->bs))
2334 7ae98627 bellard
        ret = 0;
2335 7ae98627 bellard
    else
2336 7ae98627 bellard
        ret = s->status;
2337 5391d806 bellard
#ifdef DEBUG_IDE
2338 5391d806 bellard
    printf("ide: read status addr=0x%x val=%02x\n", addr, ret);
2339 5391d806 bellard
#endif
2340 5391d806 bellard
    return ret;
2341 5391d806 bellard
}
2342 5391d806 bellard
2343 caed8802 bellard
static void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
2344 5391d806 bellard
{
2345 caed8802 bellard
    IDEState *ide_if = opaque;
2346 5391d806 bellard
    IDEState *s;
2347 5391d806 bellard
    int i;
2348 5391d806 bellard
2349 5391d806 bellard
#ifdef DEBUG_IDE
2350 5391d806 bellard
    printf("ide: write control addr=0x%x val=%02x\n", addr, val);
2351 5391d806 bellard
#endif
2352 5391d806 bellard
    /* common for both drives */
2353 5391d806 bellard
    if (!(ide_if[0].cmd & IDE_CMD_RESET) &&
2354 5391d806 bellard
        (val & IDE_CMD_RESET)) {
2355 5391d806 bellard
        /* reset low to high */
2356 5391d806 bellard
        for(i = 0;i < 2; i++) {
2357 5391d806 bellard
            s = &ide_if[i];
2358 5391d806 bellard
            s->status = BUSY_STAT | SEEK_STAT;
2359 5391d806 bellard
            s->error = 0x01;
2360 5391d806 bellard
        }
2361 5391d806 bellard
    } else if ((ide_if[0].cmd & IDE_CMD_RESET) &&
2362 5391d806 bellard
               !(val & IDE_CMD_RESET)) {
2363 5391d806 bellard
        /* high to low */
2364 5391d806 bellard
        for(i = 0;i < 2; i++) {
2365 5391d806 bellard
            s = &ide_if[i];
2366 6b136f9e bellard
            if (s->is_cdrom)
2367 6b136f9e bellard
                s->status = 0x00; /* NOTE: READY is _not_ set */
2368 6b136f9e bellard
            else
2369 56bf1d37 bellard
                s->status = READY_STAT | SEEK_STAT;
2370 5391d806 bellard
            ide_set_signature(s);
2371 5391d806 bellard
        }
2372 5391d806 bellard
    }
2373 5391d806 bellard
2374 5391d806 bellard
    ide_if[0].cmd = val;
2375 5391d806 bellard
    ide_if[1].cmd = val;
2376 5391d806 bellard
}
2377 5391d806 bellard
2378 caed8802 bellard
static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
2379 5391d806 bellard
{
2380 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
2381 5391d806 bellard
    uint8_t *p;
2382 5391d806 bellard
2383 5391d806 bellard
    p = s->data_ptr;
2384 0c4ad8dc bellard
    *(uint16_t *)p = le16_to_cpu(val);
2385 5391d806 bellard
    p += 2;
2386 5391d806 bellard
    s->data_ptr = p;
2387 5391d806 bellard
    if (p >= s->data_end)
2388 5391d806 bellard
        s->end_transfer_func(s);
2389 5391d806 bellard
}
2390 5391d806 bellard
2391 caed8802 bellard
static uint32_t ide_data_readw(void *opaque, uint32_t addr)
2392 5391d806 bellard
{
2393 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
2394 5391d806 bellard
    uint8_t *p;
2395 5391d806 bellard
    int ret;
2396 5391d806 bellard
    p = s->data_ptr;
2397 0c4ad8dc bellard
    ret = cpu_to_le16(*(uint16_t *)p);
2398 5391d806 bellard
    p += 2;
2399 5391d806 bellard
    s->data_ptr = p;
2400 5391d806 bellard
    if (p >= s->data_end)
2401 5391d806 bellard
        s->end_transfer_func(s);
2402 5391d806 bellard
    return ret;
2403 5391d806 bellard
}
2404 5391d806 bellard
2405 caed8802 bellard
static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
2406 5391d806 bellard
{
2407 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
2408 5391d806 bellard
    uint8_t *p;
2409 5391d806 bellard
2410 5391d806 bellard
    p = s->data_ptr;
2411 0c4ad8dc bellard
    *(uint32_t *)p = le32_to_cpu(val);
2412 5391d806 bellard
    p += 4;
2413 5391d806 bellard
    s->data_ptr = p;
2414 5391d806 bellard
    if (p >= s->data_end)
2415 5391d806 bellard
        s->end_transfer_func(s);
2416 5391d806 bellard
}
2417 5391d806 bellard
2418 caed8802 bellard
static uint32_t ide_data_readl(void *opaque, uint32_t addr)
2419 5391d806 bellard
{
2420 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
2421 5391d806 bellard
    uint8_t *p;
2422 5391d806 bellard
    int ret;
2423 3b46e624 ths
2424 5391d806 bellard
    p = s->data_ptr;
2425 0c4ad8dc bellard
    ret = cpu_to_le32(*(uint32_t *)p);
2426 5391d806 bellard
    p += 4;
2427 5391d806 bellard
    s->data_ptr = p;
2428 5391d806 bellard
    if (p >= s->data_end)
2429 5391d806 bellard
        s->end_transfer_func(s);
2430 5391d806 bellard
    return ret;
2431 5391d806 bellard
}
2432 5391d806 bellard
2433 a7dfe172 bellard
static void ide_dummy_transfer_stop(IDEState *s)
2434 a7dfe172 bellard
{
2435 a7dfe172 bellard
    s->data_ptr = s->io_buffer;
2436 a7dfe172 bellard
    s->data_end = s->io_buffer;
2437 a7dfe172 bellard
    s->io_buffer[0] = 0xff;
2438 a7dfe172 bellard
    s->io_buffer[1] = 0xff;
2439 a7dfe172 bellard
    s->io_buffer[2] = 0xff;
2440 a7dfe172 bellard
    s->io_buffer[3] = 0xff;
2441 a7dfe172 bellard
}
2442 a7dfe172 bellard
2443 5391d806 bellard
static void ide_reset(IDEState *s)
2444 5391d806 bellard
{
2445 201a51fc balrog
    if (s->is_cf)
2446 201a51fc balrog
        s->mult_sectors = 0;
2447 201a51fc balrog
    else
2448 201a51fc balrog
        s->mult_sectors = MAX_MULT_SECTORS;
2449 5391d806 bellard
    s->cur_drive = s;
2450 5391d806 bellard
    s->select = 0xa0;
2451 5391d806 bellard
    s->status = READY_STAT;
2452 5391d806 bellard
    ide_set_signature(s);
2453 a7dfe172 bellard
    /* init the transfer handler so that 0xffff is returned on data
2454 a7dfe172 bellard
       accesses */
2455 a7dfe172 bellard
    s->end_transfer_func = ide_dummy_transfer_stop;
2456 a7dfe172 bellard
    ide_dummy_transfer_stop(s);
2457 201a51fc balrog
    s->media_changed = 0;
2458 5391d806 bellard
}
2459 5391d806 bellard
2460 5391d806 bellard
struct partition {
2461 5391d806 bellard
        uint8_t boot_ind;                /* 0x80 - active */
2462 5391d806 bellard
        uint8_t head;                /* starting head */
2463 5391d806 bellard
        uint8_t sector;                /* starting sector */
2464 5391d806 bellard
        uint8_t cyl;                /* starting cylinder */
2465 5391d806 bellard
        uint8_t sys_ind;                /* What partition type */
2466 5391d806 bellard
        uint8_t end_head;                /* end head */
2467 5391d806 bellard
        uint8_t end_sector;        /* end sector */
2468 5391d806 bellard
        uint8_t end_cyl;                /* end cylinder */
2469 5391d806 bellard
        uint32_t start_sect;        /* starting sector counting from 0 */
2470 5391d806 bellard
        uint32_t nr_sects;                /* nr of sectors in partition */
2471 5391d806 bellard
} __attribute__((packed));
2472 5391d806 bellard
2473 bf1b938f bellard
/* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
2474 5fafdf24 ths
static int guess_disk_lchs(IDEState *s,
2475 bf1b938f bellard
                           int *pcylinders, int *pheads, int *psectors)
2476 5391d806 bellard
{
2477 c717d8bf balrog
    uint8_t *buf = s->io_buffer;
2478 46d4767d bellard
    int ret, i, heads, sectors, cylinders;
2479 5391d806 bellard
    struct partition *p;
2480 5391d806 bellard
    uint32_t nr_sects;
2481 5391d806 bellard
2482 5391d806 bellard
    ret = bdrv_read(s->bs, 0, buf, 1);
2483 33f00271 balrog
    if (ret < 0) {
2484 bf1b938f bellard
        return -1;
2485 33f00271 balrog
    }
2486 5391d806 bellard
    /* test msdos magic */
2487 33f00271 balrog
    if (buf[510] != 0x55 || buf[511] != 0xaa) {
2488 bf1b938f bellard
        return -1;
2489 33f00271 balrog
    }
2490 5391d806 bellard
    for(i = 0; i < 4; i++) {
2491 5391d806 bellard
        p = ((struct partition *)(buf + 0x1be)) + i;
2492 0c4ad8dc bellard
        nr_sects = le32_to_cpu(p->nr_sects);
2493 5391d806 bellard
        if (nr_sects && p->end_head) {
2494 5391d806 bellard
            /* We make the assumption that the partition terminates on
2495 5391d806 bellard
               a cylinder boundary */
2496 46d4767d bellard
            heads = p->end_head + 1;
2497 46d4767d bellard
            sectors = p->end_sector & 63;
2498 46d4767d bellard
            if (sectors == 0)
2499 46d4767d bellard
                continue;
2500 46d4767d bellard
            cylinders = s->nb_sectors / (heads * sectors);
2501 46d4767d bellard
            if (cylinders < 1 || cylinders > 16383)
2502 46d4767d bellard
                continue;
2503 bf1b938f bellard
            *pheads = heads;
2504 bf1b938f bellard
            *psectors = sectors;
2505 bf1b938f bellard
            *pcylinders = cylinders;
2506 5391d806 bellard
#if 0
2507 5fafdf24 ths
            printf("guessed geometry: LCHS=%d %d %d\n",
2508 bf1b938f bellard
                   cylinders, heads, sectors);
2509 5391d806 bellard
#endif
2510 bf1b938f bellard
            return 0;
2511 5391d806 bellard
        }
2512 5391d806 bellard
    }
2513 bf1b938f bellard
    return -1;
2514 5391d806 bellard
}
2515 5391d806 bellard
2516 5457c8ce bellard
static void ide_init2(IDEState *ide_state,
2517 5457c8ce bellard
                      BlockDriverState *hd0, BlockDriverState *hd1,
2518 d537cf6c pbrook
                      qemu_irq irq)
2519 5391d806 bellard
{
2520 69b91039 bellard
    IDEState *s;
2521 aedf5382 bellard
    static int drive_serial = 1;
2522 4dbb0f50 ths
    int i, cylinders, heads, secs, translation, lba_detected = 0;
2523 96b8f136 ths
    uint64_t nb_sectors;
2524 5391d806 bellard
2525 caed8802 bellard
    for(i = 0; i < 2; i++) {
2526 caed8802 bellard
        s = ide_state + i;
2527 33f00271 balrog
        s->io_buffer = qemu_memalign(512, MAX_MULT_SECTORS*512 + 4);
2528 caed8802 bellard
        if (i == 0)
2529 caed8802 bellard
            s->bs = hd0;
2530 caed8802 bellard
        else
2531 caed8802 bellard
            s->bs = hd1;
2532 5391d806 bellard
        if (s->bs) {
2533 5391d806 bellard
            bdrv_get_geometry(s->bs, &nb_sectors);
2534 5391d806 bellard
            s->nb_sectors = nb_sectors;
2535 caed8802 bellard
            /* if a geometry hint is available, use it */
2536 caed8802 bellard
            bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
2537 4dbb0f50 ths
            translation = bdrv_get_translation_hint(s->bs);
2538 caed8802 bellard
            if (cylinders != 0) {
2539 5391d806 bellard
                s->cylinders = cylinders;
2540 caed8802 bellard
                s->heads = heads;
2541 caed8802 bellard
                s->sectors = secs;
2542 caed8802 bellard
            } else {
2543 bf1b938f bellard
                if (guess_disk_lchs(s, &cylinders, &heads, &secs) == 0) {
2544 bf1b938f bellard
                    if (heads > 16) {
2545 bf1b938f bellard
                        /* if heads > 16, it means that a BIOS LBA
2546 bf1b938f bellard
                           translation was active, so the default
2547 bf1b938f bellard
                           hardware geometry is OK */
2548 4dbb0f50 ths
                        lba_detected = 1;
2549 bf1b938f bellard
                        goto default_geometry;
2550 bf1b938f bellard
                    } else {
2551 bf1b938f bellard
                        s->cylinders = cylinders;
2552 bf1b938f bellard
                        s->heads = heads;
2553 bf1b938f bellard
                        s->sectors = secs;
2554 bf1b938f bellard
                        /* disable any translation to be in sync with
2555 bf1b938f bellard
                           the logical geometry */
2556 bf1b938f bellard
                        if (translation == BIOS_ATA_TRANSLATION_AUTO) {
2557 bf1b938f bellard
                            bdrv_set_translation_hint(s->bs,
2558 bf1b938f bellard
                                                      BIOS_ATA_TRANSLATION_NONE);
2559 bf1b938f bellard
                        }
2560 bf1b938f bellard
                    }
2561 bf1b938f bellard
                } else {
2562 bf1b938f bellard
                default_geometry:
2563 46d4767d bellard
                    /* if no geometry, use a standard physical disk geometry */
2564 caed8802 bellard
                    cylinders = nb_sectors / (16 * 63);
2565 caed8802 bellard
                    if (cylinders > 16383)
2566 caed8802 bellard
                        cylinders = 16383;
2567 caed8802 bellard
                    else if (cylinders < 2)
2568 caed8802 bellard
                        cylinders = 2;
2569 caed8802 bellard
                    s->cylinders = cylinders;
2570 caed8802 bellard
                    s->heads = 16;
2571 caed8802 bellard
                    s->sectors = 63;
2572 4dbb0f50 ths
                    if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) {
2573 4dbb0f50 ths
                      if ((s->cylinders * s->heads) <= 131072) {
2574 4dbb0f50 ths
                        bdrv_set_translation_hint(s->bs,
2575 4dbb0f50 ths
                                                  BIOS_ATA_TRANSLATION_LARGE);
2576 4dbb0f50 ths
                      } else {
2577 4dbb0f50 ths
                        bdrv_set_translation_hint(s->bs,
2578 4dbb0f50 ths
                                                  BIOS_ATA_TRANSLATION_LBA);
2579 4dbb0f50 ths
                      }
2580 4dbb0f50 ths
                    }
2581 caed8802 bellard
                }
2582 769bec72 bellard
                bdrv_set_geometry_hint(s->bs, s->cylinders, s->heads, s->sectors);
2583 caed8802 bellard
            }
2584 caed8802 bellard
            if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
2585 caed8802 bellard
                s->is_cdrom = 1;
2586 bd491d6a ths
                bdrv_set_change_cb(s->bs, cdrom_change_cb, s);
2587 5391d806 bellard
            }
2588 5391d806 bellard
        }
2589 aedf5382 bellard
        s->drive_serial = drive_serial++;
2590 caed8802 bellard
        s->irq = irq;
2591 5fafdf24 ths
        s->sector_write_timer = qemu_new_timer(vm_clock,
2592 a09db21f bellard
                                               ide_sector_write_timer_cb, s);
2593 5391d806 bellard
        ide_reset(s);
2594 5391d806 bellard
    }
2595 69b91039 bellard
}
2596 69b91039 bellard
2597 34e538ae bellard
static void ide_init_ioport(IDEState *ide_state, int iobase, int iobase2)
2598 69b91039 bellard
{
2599 caed8802 bellard
    register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state);
2600 caed8802 bellard
    register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state);
2601 caed8802 bellard
    if (iobase2) {
2602 caed8802 bellard
        register_ioport_read(iobase2, 1, 1, ide_status_read, ide_state);
2603 caed8802 bellard
        register_ioport_write(iobase2, 1, 1, ide_cmd_write, ide_state);
2604 5391d806 bellard
    }
2605 3b46e624 ths
2606 caed8802 bellard
    /* data ports */
2607 caed8802 bellard
    register_ioport_write(iobase, 2, 2, ide_data_writew, ide_state);
2608 caed8802 bellard
    register_ioport_read(iobase, 2, 2, ide_data_readw, ide_state);
2609 caed8802 bellard
    register_ioport_write(iobase, 4, 4, ide_data_writel, ide_state);
2610 caed8802 bellard
    register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state);
2611 5391d806 bellard
}
2612 69b91039 bellard
2613 aa941b94 balrog
/* save per IDE drive data */
2614 aa941b94 balrog
static void ide_save(QEMUFile* f, IDEState *s)
2615 aa941b94 balrog
{
2616 bee8d684 ths
    qemu_put_be32(f, s->mult_sectors);
2617 bee8d684 ths
    qemu_put_be32(f, s->identify_set);
2618 aa941b94 balrog
    if (s->identify_set) {
2619 aa941b94 balrog
        qemu_put_buffer(f, (const uint8_t *)s->identify_data, 512);
2620 aa941b94 balrog
    }
2621 aa941b94 balrog
    qemu_put_8s(f, &s->feature);
2622 aa941b94 balrog
    qemu_put_8s(f, &s->error);
2623 aa941b94 balrog
    qemu_put_be32s(f, &s->nsector);
2624 aa941b94 balrog
    qemu_put_8s(f, &s->sector);
2625 aa941b94 balrog
    qemu_put_8s(f, &s->lcyl);
2626 aa941b94 balrog
    qemu_put_8s(f, &s->hcyl);
2627 aa941b94 balrog
    qemu_put_8s(f, &s->hob_feature);
2628 aa941b94 balrog
    qemu_put_8s(f, &s->hob_nsector);
2629 aa941b94 balrog
    qemu_put_8s(f, &s->hob_sector);
2630 aa941b94 balrog
    qemu_put_8s(f, &s->hob_lcyl);
2631 aa941b94 balrog
    qemu_put_8s(f, &s->hob_hcyl);
2632 aa941b94 balrog
    qemu_put_8s(f, &s->select);
2633 aa941b94 balrog
    qemu_put_8s(f, &s->status);
2634 aa941b94 balrog
    qemu_put_8s(f, &s->lba48);
2635 aa941b94 balrog
2636 aa941b94 balrog
    qemu_put_8s(f, &s->sense_key);
2637 aa941b94 balrog
    qemu_put_8s(f, &s->asc);
2638 aa941b94 balrog
    /* XXX: if a transfer is pending, we do not save it yet */
2639 aa941b94 balrog
}
2640 aa941b94 balrog
2641 aa941b94 balrog
/* load per IDE drive data */
2642 aa941b94 balrog
static void ide_load(QEMUFile* f, IDEState *s)
2643 aa941b94 balrog
{
2644 bee8d684 ths
    s->mult_sectors=qemu_get_be32(f);
2645 bee8d684 ths
    s->identify_set=qemu_get_be32(f);
2646 aa941b94 balrog
    if (s->identify_set) {
2647 aa941b94 balrog
        qemu_get_buffer(f, (uint8_t *)s->identify_data, 512);
2648 aa941b94 balrog
    }
2649 aa941b94 balrog
    qemu_get_8s(f, &s->feature);
2650 aa941b94 balrog
    qemu_get_8s(f, &s->error);
2651 aa941b94 balrog
    qemu_get_be32s(f, &s->nsector);
2652 aa941b94 balrog
    qemu_get_8s(f, &s->sector);
2653 aa941b94 balrog
    qemu_get_8s(f, &s->lcyl);
2654 aa941b94 balrog
    qemu_get_8s(f, &s->hcyl);
2655 aa941b94 balrog
    qemu_get_8s(f, &s->hob_feature);
2656 aa941b94 balrog
    qemu_get_8s(f, &s->hob_nsector);
2657 aa941b94 balrog
    qemu_get_8s(f, &s->hob_sector);
2658 aa941b94 balrog
    qemu_get_8s(f, &s->hob_lcyl);
2659 aa941b94 balrog
    qemu_get_8s(f, &s->hob_hcyl);
2660 aa941b94 balrog
    qemu_get_8s(f, &s->select);
2661 aa941b94 balrog
    qemu_get_8s(f, &s->status);
2662 aa941b94 balrog
    qemu_get_8s(f, &s->lba48);
2663 aa941b94 balrog
2664 aa941b94 balrog
    qemu_get_8s(f, &s->sense_key);
2665 aa941b94 balrog
    qemu_get_8s(f, &s->asc);
2666 aa941b94 balrog
    /* XXX: if a transfer is pending, we do not save it yet */
2667 aa941b94 balrog
}
2668 aa941b94 balrog
2669 69b91039 bellard
/***********************************************************/
2670 34e538ae bellard
/* ISA IDE definitions */
2671 34e538ae bellard
2672 d537cf6c pbrook
void isa_ide_init(int iobase, int iobase2, qemu_irq irq,
2673 34e538ae bellard
                  BlockDriverState *hd0, BlockDriverState *hd1)
2674 34e538ae bellard
{
2675 34e538ae bellard
    IDEState *ide_state;
2676 34e538ae bellard
2677 34e538ae bellard
    ide_state = qemu_mallocz(sizeof(IDEState) * 2);
2678 34e538ae bellard
    if (!ide_state)
2679 34e538ae bellard
        return;
2680 3b46e624 ths
2681 d537cf6c pbrook
    ide_init2(ide_state, hd0, hd1, irq);
2682 34e538ae bellard
    ide_init_ioport(ide_state, iobase, iobase2);
2683 34e538ae bellard
}
2684 34e538ae bellard
2685 34e538ae bellard
/***********************************************************/
2686 69b91039 bellard
/* PCI IDE definitions */
2687 69b91039 bellard
2688 5457c8ce bellard
static void cmd646_update_irq(PCIIDEState *d);
2689 5457c8ce bellard
2690 5fafdf24 ths
static void ide_map(PCIDevice *pci_dev, int region_num,
2691 69b91039 bellard
                    uint32_t addr, uint32_t size, int type)
2692 69b91039 bellard
{
2693 69b91039 bellard
    PCIIDEState *d = (PCIIDEState *)pci_dev;
2694 69b91039 bellard
    IDEState *ide_state;
2695 69b91039 bellard
2696 69b91039 bellard
    if (region_num <= 3) {
2697 69b91039 bellard
        ide_state = &d->ide_if[(region_num >> 1) * 2];
2698 69b91039 bellard
        if (region_num & 1) {
2699 69b91039 bellard
            register_ioport_read(addr + 2, 1, 1, ide_status_read, ide_state);
2700 69b91039 bellard
            register_ioport_write(addr + 2, 1, 1, ide_cmd_write, ide_state);
2701 69b91039 bellard
        } else {
2702 69b91039 bellard
            register_ioport_write(addr, 8, 1, ide_ioport_write, ide_state);
2703 69b91039 bellard
            register_ioport_read(addr, 8, 1, ide_ioport_read, ide_state);
2704 69b91039 bellard
2705 69b91039 bellard
            /* data ports */
2706 69b91039 bellard
            register_ioport_write(addr, 2, 2, ide_data_writew, ide_state);
2707 69b91039 bellard
            register_ioport_read(addr, 2, 2, ide_data_readw, ide_state);
2708 69b91039 bellard
            register_ioport_write(addr, 4, 4, ide_data_writel, ide_state);
2709 69b91039 bellard
            register_ioport_read(addr, 4, 4, ide_data_readl, ide_state);
2710 69b91039 bellard
        }
2711 69b91039 bellard
    }
2712 69b91039 bellard
}
2713 69b91039 bellard
2714 8ccad811 bellard
static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb)
2715 98087450 bellard
{
2716 98087450 bellard
    BMDMAState *bm = s->bmdma;
2717 98087450 bellard
    if(!bm)
2718 98087450 bellard
        return;
2719 98087450 bellard
    bm->ide_if = s;
2720 98087450 bellard
    bm->dma_cb = dma_cb;
2721 8ccad811 bellard
    bm->cur_prd_last = 0;
2722 8ccad811 bellard
    bm->cur_prd_addr = 0;
2723 8ccad811 bellard
    bm->cur_prd_len = 0;
2724 98087450 bellard
    if (bm->status & BM_STATUS_DMAING) {
2725 8ccad811 bellard
        bm->dma_cb(bm, 0);
2726 98087450 bellard
    }
2727 98087450 bellard
}
2728 98087450 bellard
2729 98087450 bellard
static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
2730 98087450 bellard
{
2731 98087450 bellard
    BMDMAState *bm = opaque;
2732 98087450 bellard
#ifdef DEBUG_IDE
2733 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2734 98087450 bellard
#endif
2735 98087450 bellard
    if (!(val & BM_CMD_START)) {
2736 98087450 bellard
        /* XXX: do it better */
2737 8ccad811 bellard
        if (bm->status & BM_STATUS_DMAING) {
2738 8ccad811 bellard
            bm->status &= ~BM_STATUS_DMAING;
2739 8ccad811 bellard
            /* cancel DMA request */
2740 8ccad811 bellard
            bm->ide_if = NULL;
2741 8ccad811 bellard
            bm->dma_cb = NULL;
2742 8ccad811 bellard
            if (bm->aiocb) {
2743 8ccad811 bellard
#ifdef DEBUG_AIO
2744 8ccad811 bellard
                printf("aio_cancel\n");
2745 8ccad811 bellard
#endif
2746 8ccad811 bellard
                bdrv_aio_cancel(bm->aiocb);
2747 8ccad811 bellard
                bm->aiocb = NULL;
2748 8ccad811 bellard
            }
2749 8ccad811 bellard
        }
2750 98087450 bellard
        bm->cmd = val & 0x09;
2751 98087450 bellard
    } else {
2752 8ccad811 bellard
        if (!(bm->status & BM_STATUS_DMAING)) {
2753 8ccad811 bellard
            bm->status |= BM_STATUS_DMAING;
2754 8ccad811 bellard
            /* start dma transfer if possible */
2755 8ccad811 bellard
            if (bm->dma_cb)
2756 8ccad811 bellard
                bm->dma_cb(bm, 0);
2757 8ccad811 bellard
        }
2758 98087450 bellard
        bm->cmd = val & 0x09;
2759 98087450 bellard
    }
2760 98087450 bellard
}
2761 98087450 bellard
2762 5457c8ce bellard
static uint32_t bmdma_readb(void *opaque, uint32_t addr)
2763 98087450 bellard
{
2764 98087450 bellard
    BMDMAState *bm = opaque;
2765 5457c8ce bellard
    PCIIDEState *pci_dev;
2766 98087450 bellard
    uint32_t val;
2767 3b46e624 ths
2768 5457c8ce bellard
    switch(addr & 3) {
2769 5fafdf24 ths
    case 0:
2770 5457c8ce bellard
        val = bm->cmd;
2771 5457c8ce bellard
        break;
2772 5457c8ce bellard
    case 1:
2773 5457c8ce bellard
        pci_dev = bm->pci_dev;
2774 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2775 5457c8ce bellard
            val = pci_dev->dev.config[MRDMODE];
2776 5457c8ce bellard
        } else {
2777 5457c8ce bellard
            val = 0xff;
2778 5457c8ce bellard
        }
2779 5457c8ce bellard
        break;
2780 5457c8ce bellard
    case 2:
2781 5457c8ce bellard
        val = bm->status;
2782 5457c8ce bellard
        break;
2783 5457c8ce bellard
    case 3:
2784 5457c8ce bellard
        pci_dev = bm->pci_dev;
2785 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2786 5457c8ce bellard
            if (bm == &pci_dev->bmdma[0])
2787 5457c8ce bellard
                val = pci_dev->dev.config[UDIDETCR0];
2788 5457c8ce bellard
            else
2789 5457c8ce bellard
                val = pci_dev->dev.config[UDIDETCR1];
2790 5457c8ce bellard
        } else {
2791 5457c8ce bellard
            val = 0xff;
2792 5457c8ce bellard
        }
2793 5457c8ce bellard
        break;
2794 5457c8ce bellard
    default:
2795 5457c8ce bellard
        val = 0xff;
2796 5457c8ce bellard
        break;
2797 5457c8ce bellard
    }
2798 98087450 bellard
#ifdef DEBUG_IDE
2799 5457c8ce bellard
    printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
2800 98087450 bellard
#endif
2801 98087450 bellard
    return val;
2802 98087450 bellard
}
2803 98087450 bellard
2804 5457c8ce bellard
static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
2805 98087450 bellard
{
2806 98087450 bellard
    BMDMAState *bm = opaque;
2807 5457c8ce bellard
    PCIIDEState *pci_dev;
2808 98087450 bellard
#ifdef DEBUG_IDE
2809 5457c8ce bellard
    printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
2810 98087450 bellard
#endif
2811 5457c8ce bellard
    switch(addr & 3) {
2812 5457c8ce bellard
    case 1:
2813 5457c8ce bellard
        pci_dev = bm->pci_dev;
2814 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2815 5fafdf24 ths
            pci_dev->dev.config[MRDMODE] =
2816 5457c8ce bellard
                (pci_dev->dev.config[MRDMODE] & ~0x30) | (val & 0x30);
2817 5457c8ce bellard
            cmd646_update_irq(pci_dev);
2818 5457c8ce bellard
        }
2819 5457c8ce bellard
        break;
2820 5457c8ce bellard
    case 2:
2821 5457c8ce bellard
        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
2822 5457c8ce bellard
        break;
2823 5457c8ce bellard
    case 3:
2824 5457c8ce bellard
        pci_dev = bm->pci_dev;
2825 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2826 5457c8ce bellard
            if (bm == &pci_dev->bmdma[0])
2827 5457c8ce bellard
                pci_dev->dev.config[UDIDETCR0] = val;
2828 5457c8ce bellard
            else
2829 5457c8ce bellard
                pci_dev->dev.config[UDIDETCR1] = val;
2830 5457c8ce bellard
        }
2831 5457c8ce bellard
        break;
2832 5457c8ce bellard
    }
2833 98087450 bellard
}
2834 98087450 bellard
2835 98087450 bellard
static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr)
2836 98087450 bellard
{
2837 98087450 bellard
    BMDMAState *bm = opaque;
2838 98087450 bellard
    uint32_t val;
2839 98087450 bellard
    val = bm->addr;
2840 98087450 bellard
#ifdef DEBUG_IDE
2841 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2842 98087450 bellard
#endif
2843 98087450 bellard
    return val;
2844 98087450 bellard
}
2845 98087450 bellard
2846 98087450 bellard
static void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val)
2847 98087450 bellard
{
2848 98087450 bellard
    BMDMAState *bm = opaque;
2849 98087450 bellard
#ifdef DEBUG_IDE
2850 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2851 98087450 bellard
#endif
2852 98087450 bellard
    bm->addr = val & ~3;
2853 30c4bbac ths
    bm->cur_addr = bm->addr;
2854 98087450 bellard
}
2855 98087450 bellard
2856 5fafdf24 ths
static void bmdma_map(PCIDevice *pci_dev, int region_num,
2857 98087450 bellard
                    uint32_t addr, uint32_t size, int type)
2858 98087450 bellard
{
2859 98087450 bellard
    PCIIDEState *d = (PCIIDEState *)pci_dev;
2860 98087450 bellard
    int i;
2861 98087450 bellard
2862 98087450 bellard
    for(i = 0;i < 2; i++) {
2863 98087450 bellard
        BMDMAState *bm = &d->bmdma[i];
2864 98087450 bellard
        d->ide_if[2 * i].bmdma = bm;
2865 98087450 bellard
        d->ide_if[2 * i + 1].bmdma = bm;
2866 5457c8ce bellard
        bm->pci_dev = (PCIIDEState *)pci_dev;
2867 5457c8ce bellard
2868 98087450 bellard
        register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
2869 98087450 bellard
2870 5457c8ce bellard
        register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
2871 5457c8ce bellard
        register_ioport_read(addr, 4, 1, bmdma_readb, bm);
2872 98087450 bellard
2873 98087450 bellard
        register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm);
2874 98087450 bellard
        register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm);
2875 98087450 bellard
        addr += 8;
2876 98087450 bellard
    }
2877 98087450 bellard
}
2878 98087450 bellard
2879 5457c8ce bellard
/* XXX: call it also when the MRDMODE is changed from the PCI config
2880 5457c8ce bellard
   registers */
2881 5457c8ce bellard
static void cmd646_update_irq(PCIIDEState *d)
2882 5457c8ce bellard
{
2883 5457c8ce bellard
    int pci_level;
2884 5457c8ce bellard
    pci_level = ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH0) &&
2885 5457c8ce bellard
                 !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH0)) ||
2886 5457c8ce bellard
        ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH1) &&
2887 5457c8ce bellard
         !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH1));
2888 d537cf6c pbrook
    qemu_set_irq(d->dev.irq[0], pci_level);
2889 5457c8ce bellard
}
2890 5457c8ce bellard
2891 5457c8ce bellard
/* the PCI irq level is the logical OR of the two channels */
2892 5457c8ce bellard
static void cmd646_set_irq(void *opaque, int channel, int level)
2893 5457c8ce bellard
{
2894 5457c8ce bellard
    PCIIDEState *d = opaque;
2895 5457c8ce bellard
    int irq_mask;
2896 5457c8ce bellard
2897 5457c8ce bellard
    irq_mask = MRDMODE_INTR_CH0 << channel;
2898 5457c8ce bellard
    if (level)
2899 5457c8ce bellard
        d->dev.config[MRDMODE] |= irq_mask;
2900 5457c8ce bellard
    else
2901 5457c8ce bellard
        d->dev.config[MRDMODE] &= ~irq_mask;
2902 5457c8ce bellard
    cmd646_update_irq(d);
2903 5457c8ce bellard
}
2904 5457c8ce bellard
2905 5457c8ce bellard
/* CMD646 PCI IDE controller */
2906 5457c8ce bellard
void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
2907 5457c8ce bellard
                         int secondary_ide_enabled)
2908 69b91039 bellard
{
2909 69b91039 bellard
    PCIIDEState *d;
2910 69b91039 bellard
    uint8_t *pci_conf;
2911 34e538ae bellard
    int i;
2912 d537cf6c pbrook
    qemu_irq *irq;
2913 34e538ae bellard
2914 5fafdf24 ths
    d = (PCIIDEState *)pci_register_device(bus, "CMD646 IDE",
2915 5457c8ce bellard
                                           sizeof(PCIIDEState),
2916 5fafdf24 ths
                                           -1,
2917 73c11f63 bellard
                                           NULL, NULL);
2918 5457c8ce bellard
    d->type = IDE_TYPE_CMD646;
2919 69b91039 bellard
    pci_conf = d->dev.config;
2920 5457c8ce bellard
    pci_conf[0x00] = 0x95; // CMD646
2921 5457c8ce bellard
    pci_conf[0x01] = 0x10;
2922 5457c8ce bellard
    pci_conf[0x02] = 0x46;
2923 5457c8ce bellard
    pci_conf[0x03] = 0x06;
2924 5457c8ce bellard
2925 5457c8ce bellard
    pci_conf[0x08] = 0x07; // IDE controller revision
2926 5fafdf24 ths
    pci_conf[0x09] = 0x8f;
2927 5457c8ce bellard
2928 69b91039 bellard
    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
2929 69b91039 bellard
    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
2930 5457c8ce bellard
    pci_conf[0x0e] = 0x00; // header_type
2931 3b46e624 ths
2932 5457c8ce bellard
    if (secondary_ide_enabled) {
2933 5457c8ce bellard
        /* XXX: if not enabled, really disable the seconday IDE controller */
2934 5457c8ce bellard
        pci_conf[0x51] = 0x80; /* enable IDE1 */
2935 5457c8ce bellard
    }
2936 69b91039 bellard
2937 5fafdf24 ths
    pci_register_io_region((PCIDevice *)d, 0, 0x8,
2938 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2939 5fafdf24 ths
    pci_register_io_region((PCIDevice *)d, 1, 0x4,
2940 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2941 5fafdf24 ths
    pci_register_io_region((PCIDevice *)d, 2, 0x8,
2942 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2943 5fafdf24 ths
    pci_register_io_region((PCIDevice *)d, 3, 0x4,
2944 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2945 5fafdf24 ths
    pci_register_io_region((PCIDevice *)d, 4, 0x10,
2946 98087450 bellard
                           PCI_ADDRESS_SPACE_IO, bmdma_map);
2947 69b91039 bellard
2948 34e538ae bellard
    pci_conf[0x3d] = 0x01; // interrupt on pin 1
2949 3b46e624 ths
2950 34e538ae bellard
    for(i = 0; i < 4; i++)
2951 34e538ae bellard
        d->ide_if[i].pci_dev = (PCIDevice *)d;
2952 d537cf6c pbrook
2953 d537cf6c pbrook
    irq = qemu_allocate_irqs(cmd646_set_irq, d, 2);
2954 d537cf6c pbrook
    ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], irq[0]);
2955 d537cf6c pbrook
    ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], irq[1]);
2956 34e538ae bellard
}
2957 34e538ae bellard
2958 c3d78997 bellard
static void pci_ide_save(QEMUFile* f, void *opaque)
2959 c3d78997 bellard
{
2960 c3d78997 bellard
    PCIIDEState *d = opaque;
2961 c3d78997 bellard
    int i;
2962 c3d78997 bellard
2963 c3d78997 bellard
    pci_device_save(&d->dev, f);
2964 c3d78997 bellard
2965 c3d78997 bellard
    for(i = 0; i < 2; i++) {
2966 c3d78997 bellard
        BMDMAState *bm = &d->bmdma[i];
2967 c3d78997 bellard
        qemu_put_8s(f, &bm->cmd);
2968 c3d78997 bellard
        qemu_put_8s(f, &bm->status);
2969 c3d78997 bellard
        qemu_put_be32s(f, &bm->addr);
2970 c3d78997 bellard
        /* XXX: if a transfer is pending, we do not save it yet */
2971 c3d78997 bellard
    }
2972 c3d78997 bellard
2973 c3d78997 bellard
    /* per IDE interface data */
2974 c3d78997 bellard
    for(i = 0; i < 2; i++) {
2975 c3d78997 bellard
        IDEState *s = &d->ide_if[i * 2];
2976 c3d78997 bellard
        uint8_t drive1_selected;
2977 c3d78997 bellard
        qemu_put_8s(f, &s->cmd);
2978 c3d78997 bellard
        drive1_selected = (s->cur_drive != s);
2979 c3d78997 bellard
        qemu_put_8s(f, &drive1_selected);
2980 c3d78997 bellard
    }
2981 c3d78997 bellard
2982 c3d78997 bellard
    /* per IDE drive data */
2983 c3d78997 bellard
    for(i = 0; i < 4; i++) {
2984 aa941b94 balrog
        ide_save(f, &d->ide_if[i]);
2985 c3d78997 bellard
    }
2986 c3d78997 bellard
}
2987 c3d78997 bellard
2988 c3d78997 bellard
static int pci_ide_load(QEMUFile* f, void *opaque, int version_id)
2989 c3d78997 bellard
{
2990 c3d78997 bellard
    PCIIDEState *d = opaque;
2991 c3d78997 bellard
    int ret, i;
2992 c3d78997 bellard
2993 c3d78997 bellard
    if (version_id != 1)
2994 c3d78997 bellard
        return -EINVAL;
2995 c3d78997 bellard
    ret = pci_device_load(&d->dev, f);
2996 c3d78997 bellard
    if (ret < 0)
2997 c3d78997 bellard
        return ret;
2998 c3d78997 bellard
2999 c3d78997 bellard
    for(i = 0; i < 2; i++) {
3000 c3d78997 bellard
        BMDMAState *bm = &d->bmdma[i];
3001 c3d78997 bellard
        qemu_get_8s(f, &bm->cmd);
3002 c3d78997 bellard
        qemu_get_8s(f, &bm->status);
3003 c3d78997 bellard
        qemu_get_be32s(f, &bm->addr);
3004 c3d78997 bellard
        /* XXX: if a transfer is pending, we do not save it yet */
3005 c3d78997 bellard
    }
3006 c3d78997 bellard
3007 c3d78997 bellard
    /* per IDE interface data */
3008 c3d78997 bellard
    for(i = 0; i < 2; i++) {
3009 c3d78997 bellard
        IDEState *s = &d->ide_if[i * 2];
3010 c3d78997 bellard
        uint8_t drive1_selected;
3011 c3d78997 bellard
        qemu_get_8s(f, &s->cmd);
3012 c3d78997 bellard
        qemu_get_8s(f, &drive1_selected);
3013 c3d78997 bellard
        s->cur_drive = &d->ide_if[i * 2 + (drive1_selected != 0)];
3014 c3d78997 bellard
    }
3015 c3d78997 bellard
3016 c3d78997 bellard
    /* per IDE drive data */
3017 c3d78997 bellard
    for(i = 0; i < 4; i++) {
3018 aa941b94 balrog
        ide_load(f, &d->ide_if[i]);
3019 c3d78997 bellard
    }
3020 c3d78997 bellard
    return 0;
3021 c3d78997 bellard
}
3022 c3d78997 bellard
3023 e6a71ae3 ths
static void piix3_reset(PCIIDEState *d)
3024 e6a71ae3 ths
{
3025 e6a71ae3 ths
    uint8_t *pci_conf = d->dev.config;
3026 e6a71ae3 ths
3027 e6a71ae3 ths
    pci_conf[0x04] = 0x00;
3028 e6a71ae3 ths
    pci_conf[0x05] = 0x00;
3029 e6a71ae3 ths
    pci_conf[0x06] = 0x80; /* FBC */
3030 e6a71ae3 ths
    pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
3031 e6a71ae3 ths
    pci_conf[0x20] = 0x01; /* BMIBA: 20-23h */
3032 e6a71ae3 ths
}
3033 e6a71ae3 ths
3034 34e538ae bellard
/* hd_table must contain 4 block drivers */
3035 34e538ae bellard
/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
3036 d537cf6c pbrook
void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
3037 d537cf6c pbrook
                        qemu_irq *pic)
3038 34e538ae bellard
{
3039 34e538ae bellard
    PCIIDEState *d;
3040 34e538ae bellard
    uint8_t *pci_conf;
3041 3b46e624 ths
3042 34e538ae bellard
    /* register a function 1 of PIIX3 */
3043 5fafdf24 ths
    d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE",
3044 46e50e9d bellard
                                           sizeof(PCIIDEState),
3045 502a5395 pbrook
                                           devfn,
3046 34e538ae bellard
                                           NULL, NULL);
3047 5457c8ce bellard
    d->type = IDE_TYPE_PIIX3;
3048 5457c8ce bellard
3049 34e538ae bellard
    pci_conf = d->dev.config;
3050 34e538ae bellard
    pci_conf[0x00] = 0x86; // Intel
3051 34e538ae bellard
    pci_conf[0x01] = 0x80;
3052 34e538ae bellard
    pci_conf[0x02] = 0x10;
3053 34e538ae bellard
    pci_conf[0x03] = 0x70;
3054 92510b8c bellard
    pci_conf[0x09] = 0x80; // legacy ATA mode
3055 34e538ae bellard
    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
3056 34e538ae bellard
    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
3057 34e538ae bellard
    pci_conf[0x0e] = 0x00; // header_type
3058 34e538ae bellard
3059 e6a71ae3 ths
    piix3_reset(d);
3060 e6a71ae3 ths
3061 5fafdf24 ths
    pci_register_io_region((PCIDevice *)d, 4, 0x10,
3062 98087450 bellard
                           PCI_ADDRESS_SPACE_IO, bmdma_map);
3063 34e538ae bellard
3064 d537cf6c pbrook
    ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], pic[14]);
3065 d537cf6c pbrook
    ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], pic[15]);
3066 34e538ae bellard
    ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
3067 34e538ae bellard
    ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
3068 c3d78997 bellard
3069 c3d78997 bellard
    register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
3070 69b91039 bellard
}
3071 1ade1de2 bellard
3072 afcc3cdf ths
/* hd_table must contain 4 block drivers */
3073 afcc3cdf ths
/* NOTE: for the PIIX4, the IRQs and IOports are hardcoded */
3074 afcc3cdf ths
void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
3075 afcc3cdf ths
                        qemu_irq *pic)
3076 afcc3cdf ths
{
3077 afcc3cdf ths
    PCIIDEState *d;
3078 afcc3cdf ths
    uint8_t *pci_conf;
3079 afcc3cdf ths
3080 afcc3cdf ths
    /* register a function 1 of PIIX4 */
3081 afcc3cdf ths
    d = (PCIIDEState *)pci_register_device(bus, "PIIX4 IDE",
3082 afcc3cdf ths
                                           sizeof(PCIIDEState),
3083 afcc3cdf ths
                                           devfn,
3084 afcc3cdf ths
                                           NULL, NULL);
3085 afcc3cdf ths
    d->type = IDE_TYPE_PIIX4;
3086 afcc3cdf ths
3087 afcc3cdf ths
    pci_conf = d->dev.config;
3088 afcc3cdf ths
    pci_conf[0x00] = 0x86; // Intel
3089 afcc3cdf ths
    pci_conf[0x01] = 0x80;
3090 afcc3cdf ths
    pci_conf[0x02] = 0x11;
3091 afcc3cdf ths
    pci_conf[0x03] = 0x71;
3092 afcc3cdf ths
    pci_conf[0x09] = 0x80; // legacy ATA mode
3093 afcc3cdf ths
    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
3094 afcc3cdf ths
    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
3095 afcc3cdf ths
    pci_conf[0x0e] = 0x00; // header_type
3096 afcc3cdf ths
3097 afcc3cdf ths
    piix3_reset(d);
3098 afcc3cdf ths
3099 afcc3cdf ths
    pci_register_io_region((PCIDevice *)d, 4, 0x10,
3100 afcc3cdf ths
                           PCI_ADDRESS_SPACE_IO, bmdma_map);
3101 afcc3cdf ths
3102 afcc3cdf ths
    ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], pic[14]);
3103 afcc3cdf ths
    ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], pic[15]);
3104 afcc3cdf ths
    ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
3105 afcc3cdf ths
    ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
3106 afcc3cdf ths
3107 afcc3cdf ths
    register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
3108 afcc3cdf ths
}
3109 afcc3cdf ths
3110 1ade1de2 bellard
/***********************************************************/
3111 1ade1de2 bellard
/* MacIO based PowerPC IDE */
3112 1ade1de2 bellard
3113 1ade1de2 bellard
/* PowerMac IDE memory IO */
3114 1ade1de2 bellard
static void pmac_ide_writeb (void *opaque,
3115 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
3116 1ade1de2 bellard
{
3117 5fafdf24 ths
    addr = (addr & 0xFFF) >> 4;
3118 1ade1de2 bellard
    switch (addr) {
3119 1ade1de2 bellard
    case 1 ... 7:
3120 1ade1de2 bellard
        ide_ioport_write(opaque, addr, val);
3121 1ade1de2 bellard
        break;
3122 1ade1de2 bellard
    case 8:
3123 1ade1de2 bellard
    case 22:
3124 1ade1de2 bellard
        ide_cmd_write(opaque, 0, val);
3125 1ade1de2 bellard
        break;
3126 1ade1de2 bellard
    default:
3127 1ade1de2 bellard
        break;
3128 1ade1de2 bellard
    }
3129 1ade1de2 bellard
}
3130 1ade1de2 bellard
3131 1ade1de2 bellard
static uint32_t pmac_ide_readb (void *opaque,target_phys_addr_t addr)
3132 1ade1de2 bellard
{
3133 1ade1de2 bellard
    uint8_t retval;
3134 1ade1de2 bellard
3135 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4;
3136 1ade1de2 bellard
    switch (addr) {
3137 1ade1de2 bellard
    case 1 ... 7:
3138 1ade1de2 bellard
        retval = ide_ioport_read(opaque, addr);
3139 1ade1de2 bellard
        break;
3140 1ade1de2 bellard
    case 8:
3141 1ade1de2 bellard
    case 22:
3142 1ade1de2 bellard
        retval = ide_status_read(opaque, 0);
3143 1ade1de2 bellard
        break;
3144 1ade1de2 bellard
    default:
3145 1ade1de2 bellard
        retval = 0xFF;
3146 1ade1de2 bellard
        break;
3147 1ade1de2 bellard
    }
3148 1ade1de2 bellard
    return retval;
3149 1ade1de2 bellard
}
3150 1ade1de2 bellard
3151 1ade1de2 bellard
static void pmac_ide_writew (void *opaque,
3152 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
3153 1ade1de2 bellard
{
3154 5fafdf24 ths
    addr = (addr & 0xFFF) >> 4;
3155 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
3156 1ade1de2 bellard
    val = bswap16(val);
3157 1ade1de2 bellard
#endif
3158 1ade1de2 bellard
    if (addr == 0) {
3159 1ade1de2 bellard
        ide_data_writew(opaque, 0, val);
3160 1ade1de2 bellard
    }
3161 1ade1de2 bellard
}
3162 1ade1de2 bellard
3163 1ade1de2 bellard
static uint32_t pmac_ide_readw (void *opaque,target_phys_addr_t addr)
3164 1ade1de2 bellard
{
3165 1ade1de2 bellard
    uint16_t retval;
3166 1ade1de2 bellard
3167 5fafdf24 ths
    addr = (addr & 0xFFF) >> 4;
3168 1ade1de2 bellard
    if (addr == 0) {
3169 1ade1de2 bellard
        retval = ide_data_readw(opaque, 0);
3170 1ade1de2 bellard
    } else {
3171 1ade1de2 bellard
        retval = 0xFFFF;
3172 1ade1de2 bellard
    }
3173 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
3174 1ade1de2 bellard
    retval = bswap16(retval);
3175 1ade1de2 bellard
#endif
3176 1ade1de2 bellard
    return retval;
3177 1ade1de2 bellard
}
3178 1ade1de2 bellard
3179 1ade1de2 bellard
static void pmac_ide_writel (void *opaque,
3180 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
3181 1ade1de2 bellard
{
3182 5fafdf24 ths
    addr = (addr & 0xFFF) >> 4;
3183 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
3184 1ade1de2 bellard
    val = bswap32(val);
3185 1ade1de2 bellard
#endif
3186 1ade1de2 bellard
    if (addr == 0) {
3187 1ade1de2 bellard
        ide_data_writel(opaque, 0, val);
3188 1ade1de2 bellard
    }
3189 1ade1de2 bellard
}
3190 1ade1de2 bellard
3191 1ade1de2 bellard
static uint32_t pmac_ide_readl (void *opaque,target_phys_addr_t addr)
3192 1ade1de2 bellard
{
3193 1ade1de2 bellard
    uint32_t retval;
3194 1ade1de2 bellard
3195 5fafdf24 ths
    addr = (addr & 0xFFF) >> 4;
3196 1ade1de2 bellard
    if (addr == 0) {
3197 1ade1de2 bellard
        retval = ide_data_readl(opaque, 0);
3198 1ade1de2 bellard
    } else {
3199 1ade1de2 bellard
        retval = 0xFFFFFFFF;
3200 1ade1de2 bellard
    }
3201 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
3202 1ade1de2 bellard
    retval = bswap32(retval);
3203 1ade1de2 bellard
#endif
3204 1ade1de2 bellard
    return retval;
3205 1ade1de2 bellard
}
3206 1ade1de2 bellard
3207 1ade1de2 bellard
static CPUWriteMemoryFunc *pmac_ide_write[] = {
3208 1ade1de2 bellard
    pmac_ide_writeb,
3209 1ade1de2 bellard
    pmac_ide_writew,
3210 1ade1de2 bellard
    pmac_ide_writel,
3211 1ade1de2 bellard
};
3212 1ade1de2 bellard
3213 1ade1de2 bellard
static CPUReadMemoryFunc *pmac_ide_read[] = {
3214 1ade1de2 bellard
    pmac_ide_readb,
3215 1ade1de2 bellard
    pmac_ide_readw,
3216 1ade1de2 bellard
    pmac_ide_readl,
3217 1ade1de2 bellard
};
3218 1ade1de2 bellard
3219 1ade1de2 bellard
/* hd_table must contain 4 block drivers */
3220 1ade1de2 bellard
/* PowerMac uses memory mapped registers, not I/O. Return the memory
3221 1ade1de2 bellard
   I/O index to access the ide. */
3222 d537cf6c pbrook
int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq)
3223 1ade1de2 bellard
{
3224 1ade1de2 bellard
    IDEState *ide_if;
3225 1ade1de2 bellard
    int pmac_ide_memory;
3226 1ade1de2 bellard
3227 1ade1de2 bellard
    ide_if = qemu_mallocz(sizeof(IDEState) * 2);
3228 d537cf6c pbrook
    ide_init2(&ide_if[0], hd_table[0], hd_table[1], irq);
3229 3b46e624 ths
3230 1ade1de2 bellard
    pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
3231 1ade1de2 bellard
                                             pmac_ide_write, &ide_if[0]);
3232 1ade1de2 bellard
    return pmac_ide_memory;
3233 1ade1de2 bellard
}
3234 201a51fc balrog
3235 201a51fc balrog
/***********************************************************/
3236 201a51fc balrog
/* CF-ATA Microdrive */
3237 201a51fc balrog
3238 201a51fc balrog
#define METADATA_SIZE        0x20
3239 201a51fc balrog
3240 201a51fc balrog
/* DSCM-1XXXX Microdrive hard disk with CF+ II / PCMCIA interface.  */
3241 201a51fc balrog
struct md_s {
3242 201a51fc balrog
    IDEState ide[2];
3243 201a51fc balrog
    struct pcmcia_card_s card;
3244 201a51fc balrog
    uint32_t attr_base;
3245 201a51fc balrog
    uint32_t io_base;
3246 201a51fc balrog
3247 201a51fc balrog
    /* Card state */
3248 201a51fc balrog
    uint8_t opt;
3249 201a51fc balrog
    uint8_t stat;
3250 201a51fc balrog
    uint8_t pins;
3251 201a51fc balrog
3252 201a51fc balrog
    uint8_t ctrl;
3253 201a51fc balrog
    uint16_t io;
3254 201a51fc balrog
    int cycle;
3255 201a51fc balrog
};
3256 201a51fc balrog
3257 201a51fc balrog
/* Register bitfields */
3258 201a51fc balrog
enum md_opt {
3259 201a51fc balrog
    OPT_MODE_MMAP        = 0,
3260 201a51fc balrog
    OPT_MODE_IOMAP16        = 1,
3261 201a51fc balrog
    OPT_MODE_IOMAP1        = 2,
3262 201a51fc balrog
    OPT_MODE_IOMAP2        = 3,
3263 201a51fc balrog
    OPT_MODE                = 0x3f,
3264 201a51fc balrog
    OPT_LEVIREQ                = 0x40,
3265 201a51fc balrog
    OPT_SRESET                = 0x80,
3266 201a51fc balrog
};
3267 201a51fc balrog
enum md_cstat {
3268 201a51fc balrog
    STAT_INT                = 0x02,
3269 201a51fc balrog
    STAT_PWRDWN                = 0x04,
3270 201a51fc balrog
    STAT_XE                = 0x10,
3271 201a51fc balrog
    STAT_IOIS8                = 0x20,
3272 201a51fc balrog
    STAT_SIGCHG                = 0x40,
3273 201a51fc balrog
    STAT_CHANGED        = 0x80,
3274 201a51fc balrog
};
3275 201a51fc balrog
enum md_pins {
3276 201a51fc balrog
    PINS_MRDY                = 0x02,
3277 201a51fc balrog
    PINS_CRDY                = 0x20,
3278 201a51fc balrog
};
3279 201a51fc balrog
enum md_ctrl {
3280 201a51fc balrog
    CTRL_IEN                = 0x02,
3281 201a51fc balrog
    CTRL_SRST                = 0x04,
3282 201a51fc balrog
};
3283 201a51fc balrog
3284 201a51fc balrog
static inline void md_interrupt_update(struct md_s *s)
3285 201a51fc balrog
{
3286 201a51fc balrog
    if (!s->card.slot)
3287 201a51fc balrog
        return;
3288 201a51fc balrog
3289 201a51fc balrog
    qemu_set_irq(s->card.slot->irq,
3290 201a51fc balrog
                    !(s->stat & STAT_INT) &&        /* Inverted */
3291 201a51fc balrog
                    !(s->ctrl & (CTRL_IEN | CTRL_SRST)) &&
3292 201a51fc balrog
                    !(s->opt & OPT_SRESET));
3293 201a51fc balrog
}
3294 201a51fc balrog
3295 201a51fc balrog
static void md_set_irq(void *opaque, int irq, int level)
3296 201a51fc balrog
{
3297 201a51fc balrog
    struct md_s *s = (struct md_s *) opaque;
3298 201a51fc balrog
    if (level)
3299 201a51fc balrog
        s->stat |= STAT_INT;
3300 201a51fc balrog
    else
3301 201a51fc balrog
        s->stat &= ~STAT_INT;
3302 201a51fc balrog
3303 201a51fc balrog
    md_interrupt_update(s);
3304 201a51fc balrog
}
3305 201a51fc balrog
3306 201a51fc balrog
static void md_reset(struct md_s *s)
3307 201a51fc balrog
{
3308 201a51fc balrog
    s->opt = OPT_MODE_MMAP;
3309 201a51fc balrog
    s->stat = 0;
3310 201a51fc balrog
    s->pins = 0;
3311 201a51fc balrog
    s->cycle = 0;
3312 201a51fc balrog
    s->ctrl = 0;
3313 201a51fc balrog
    ide_reset(s->ide);
3314 201a51fc balrog
}
3315 201a51fc balrog
3316 9e315fa9 balrog
static uint8_t md_attr_read(void *opaque, uint32_t at)
3317 201a51fc balrog
{
3318 201a51fc balrog
    struct md_s *s = (struct md_s *) opaque;
3319 201a51fc balrog
    if (at < s->attr_base) {
3320 201a51fc balrog
        if (at < s->card.cis_len)
3321 201a51fc balrog
            return s->card.cis[at];
3322 201a51fc balrog
        else
3323 201a51fc balrog
            return 0x00;
3324 201a51fc balrog
    }
3325 201a51fc balrog
3326 201a51fc balrog
    at -= s->attr_base;
3327 201a51fc balrog
3328 201a51fc balrog
    switch (at) {
3329 201a51fc balrog
    case 0x00:        /* Configuration Option Register */
3330 201a51fc balrog
        return s->opt;
3331 201a51fc balrog
    case 0x02:        /* Card Configuration Status Register */
3332 201a51fc balrog
        if (s->ctrl & CTRL_IEN)
3333 201a51fc balrog
            return s->stat & ~STAT_INT;
3334 201a51fc balrog
        else
3335 201a51fc balrog
            return s->stat;
3336 201a51fc balrog
    case 0x04:        /* Pin Replacement Register */
3337 201a51fc balrog
        return (s->pins & PINS_CRDY) | 0x0c;
3338 201a51fc balrog
    case 0x06:        /* Socket and Copy Register */
3339 201a51fc balrog
        return 0x00;
3340 201a51fc balrog
#ifdef VERBOSE
3341 201a51fc balrog
    default:
3342 201a51fc balrog
        printf("%s: Bad attribute space register %02x\n", __FUNCTION__, at);
3343 201a51fc balrog
#endif
3344 201a51fc balrog
    }
3345 201a51fc balrog
3346 201a51fc balrog
    return 0;
3347 201a51fc balrog
}
3348 201a51fc balrog
3349 9e315fa9 balrog
static void md_attr_write(void *opaque, uint32_t at, uint8_t value)
3350 201a51fc balrog
{
3351 201a51fc balrog
    struct md_s *s = (struct md_s *) opaque;
3352 201a51fc balrog
    at -= s->attr_base;
3353 201a51fc balrog
3354 201a51fc balrog
    switch (at) {
3355 201a51fc balrog
    case 0x00:        /* Configuration Option Register */
3356 201a51fc balrog
        s->opt = value & 0xcf;
3357 201a51fc balrog
        if (value & OPT_SRESET)
3358 201a51fc balrog
            md_reset(s);
3359 201a51fc balrog
        md_interrupt_update(s);
3360 201a51fc balrog
        break;
3361 201a51fc balrog
    case 0x02:        /* Card Configuration Status Register */
3362 201a51fc balrog
        if ((s->stat ^ value) & STAT_PWRDWN)
3363 201a51fc balrog
            s->pins |= PINS_CRDY;
3364 201a51fc balrog
        s->stat &= 0x82;
3365 201a51fc balrog
        s->stat |= value & 0x74;
3366 201a51fc balrog
        md_interrupt_update(s);
3367 201a51fc balrog
        /* Word 170 in Identify Device must be equal to STAT_XE */
3368 201a51fc balrog
        break;
3369 201a51fc balrog
    case 0x04:        /* Pin Replacement Register */
3370 201a51fc balrog
        s->pins &= PINS_CRDY;
3371 201a51fc balrog
        s->pins |= value & PINS_MRDY;
3372 201a51fc balrog
        break;
3373 201a51fc balrog
    case 0x06:        /* Socket and Copy Register */
3374 201a51fc balrog
        break;
3375 201a51fc balrog
    default:
3376 201a51fc balrog
        printf("%s: Bad attribute space register %02x\n", __FUNCTION__, at);
3377 201a51fc balrog
    }
3378 201a51fc balrog
}
3379 201a51fc balrog
3380 9e315fa9 balrog
static uint16_t md_common_read(void *opaque, uint32_t at)
3381 201a51fc balrog
{
3382 201a51fc balrog
    struct md_s *s = (struct md_s *) opaque;
3383 201a51fc balrog
    uint16_t ret;
3384 201a51fc balrog
    at -= s->io_base;
3385 201a51fc balrog
3386 201a51fc balrog
    switch (s->opt & OPT_MODE) {
3387 201a51fc balrog
    case OPT_MODE_MMAP:
3388 201a51fc balrog
        if ((at & ~0x3ff) == 0x400)
3389 201a51fc balrog
            at = 0;
3390 201a51fc balrog
        break;
3391 201a51fc balrog
    case OPT_MODE_IOMAP16:
3392 201a51fc balrog
        at &= 0xf;
3393 201a51fc balrog
        break;
3394 201a51fc balrog
    case OPT_MODE_IOMAP1:
3395 201a51fc balrog
        if ((at & ~0xf) == 0x3f0)
3396 201a51fc balrog
            at -= 0x3e8;
3397 201a51fc balrog
        else if ((at & ~0xf) == 0x1f0)
3398 201a51fc balrog
            at -= 0x1f0;
3399 201a51fc balrog
        break;
3400 201a51fc balrog
    case OPT_MODE_IOMAP2:
3401 201a51fc balrog
        if ((at & ~0xf) == 0x370)
3402 201a51fc balrog
            at -= 0x368;
3403 201a51fc balrog
        else if ((at & ~0xf) == 0x170)
3404 201a51fc balrog
            at -= 0x170;
3405 201a51fc balrog
    }
3406 201a51fc balrog
3407 201a51fc balrog
    switch (at) {
3408 201a51fc balrog
    case 0x0:        /* Even RD Data */
3409 201a51fc balrog
    case 0x8:
3410 201a51fc balrog
        return ide_data_readw(s->ide, 0);
3411 201a51fc balrog
3412 201a51fc balrog
        /* TODO: 8-bit accesses */
3413 201a51fc balrog
        if (s->cycle)
3414 201a51fc balrog
            ret = s->io >> 8;
3415 201a51fc balrog
        else {
3416 201a51fc balrog
            s->io = ide_data_readw(s->ide, 0);
3417 201a51fc balrog
            ret = s->io & 0xff;
3418 201a51fc balrog
        }
3419 201a51fc balrog
        s->cycle = !s->cycle;
3420 201a51fc balrog
        return ret;
3421 201a51fc balrog
    case 0x9:        /* Odd RD Data */
3422 201a51fc balrog
        return s->io >> 8;
3423 201a51fc balrog
    case 0xd:        /* Error */
3424 201a51fc balrog
        return ide_ioport_read(s->ide, 0x1);
3425 201a51fc balrog
    case 0xe:        /* Alternate Status */
3426 201a51fc balrog
        if (s->ide->cur_drive->bs)
3427 201a51fc balrog
            return s->ide->cur_drive->status;
3428 201a51fc balrog
        else
3429 201a51fc balrog
            return 0;
3430 201a51fc balrog
    case 0xf:        /* Device Address */
3431 201a51fc balrog
        return 0xc2 | ((~s->ide->select << 2) & 0x3c);
3432 201a51fc balrog
    default:
3433 201a51fc balrog
        return ide_ioport_read(s->ide, at);
3434 201a51fc balrog
    }
3435 201a51fc balrog
3436 201a51fc balrog
    return 0;
3437 201a51fc balrog
}
3438 201a51fc balrog
3439 9e315fa9 balrog
static void md_common_write(void *opaque, uint32_t at, uint16_t value)
3440 201a51fc balrog
{
3441 201a51fc balrog
    struct md_s *s = (struct md_s *) opaque;
3442 201a51fc balrog
    at -= s->io_base;
3443 201a51fc balrog
3444 201a51fc balrog
    switch (s->opt & OPT_MODE) {
3445 201a51fc balrog
    case OPT_MODE_MMAP:
3446 201a51fc balrog
        if ((at & ~0x3ff) == 0x400)
3447 201a51fc balrog
            at = 0;
3448 201a51fc balrog
        break;
3449 201a51fc balrog
    case OPT_MODE_IOMAP16:
3450 201a51fc balrog
        at &= 0xf;
3451 201a51fc balrog
        break;
3452 201a51fc balrog
    case OPT_MODE_IOMAP1:
3453 201a51fc balrog
        if ((at & ~0xf) == 0x3f0)
3454 201a51fc balrog
            at -= 0x3e8;
3455 201a51fc balrog
        else if ((at & ~0xf) == 0x1f0)
3456 201a51fc balrog
            at -= 0x1f0;
3457 201a51fc balrog
        break;
3458 201a51fc balrog
    case OPT_MODE_IOMAP2:
3459 201a51fc balrog
        if ((at & ~0xf) == 0x370)
3460 201a51fc balrog
            at -= 0x368;
3461 201a51fc balrog
        else if ((at & ~0xf) == 0x170)
3462 201a51fc balrog
            at -= 0x170;
3463 201a51fc balrog
    }
3464 201a51fc balrog
3465 201a51fc balrog
    switch (at) {
3466 201a51fc balrog
    case 0x0:        /* Even WR Data */
3467 201a51fc balrog
    case 0x8:
3468 201a51fc balrog
        ide_data_writew(s->ide, 0, value);
3469 201a51fc balrog
        break;
3470 201a51fc balrog
3471 201a51fc balrog
        /* TODO: 8-bit accesses */
3472 201a51fc balrog
        if (s->cycle)
3473 201a51fc balrog
            ide_data_writew(s->ide, 0, s->io | (value << 8));
3474 201a51fc balrog
        else
3475 201a51fc balrog
            s->io = value & 0xff;
3476 201a51fc balrog
        s->cycle = !s->cycle;
3477 201a51fc balrog
        break;
3478 201a51fc balrog
    case 0x9:
3479 201a51fc balrog
        s->io = value & 0xff;
3480 201a51fc balrog
        s->cycle = !s->cycle;
3481 201a51fc balrog
        break;
3482 201a51fc balrog
    case 0xd:        /* Features */
3483 201a51fc balrog
        ide_ioport_write(s->ide, 0x1, value);
3484 201a51fc balrog
        break;
3485 201a51fc balrog
    case 0xe:        /* Device Control */
3486 201a51fc balrog
        s->ctrl = value;
3487 201a51fc balrog
        if (value & CTRL_SRST)
3488 201a51fc balrog
            md_reset(s);
3489 201a51fc balrog
        md_interrupt_update(s);
3490 201a51fc balrog
        break;
3491 201a51fc balrog
    default:
3492 201a51fc balrog
        if (s->stat & STAT_PWRDWN) {
3493 201a51fc balrog
            s->pins |= PINS_CRDY;
3494 201a51fc balrog
            s->stat &= ~STAT_PWRDWN;
3495 201a51fc balrog
        }
3496 201a51fc balrog
        ide_ioport_write(s->ide, at, value);
3497 201a51fc balrog
    }
3498 201a51fc balrog
}
3499 201a51fc balrog
3500 aa941b94 balrog
static void md_save(QEMUFile *f, void *opaque)
3501 aa941b94 balrog
{
3502 aa941b94 balrog
    struct md_s *s = (struct md_s *) opaque;
3503 aa941b94 balrog
    int i;
3504 aa941b94 balrog
    uint8_t drive1_selected;
3505 aa941b94 balrog
3506 aa941b94 balrog
    qemu_put_8s(f, &s->opt);
3507 aa941b94 balrog
    qemu_put_8s(f, &s->stat);
3508 aa941b94 balrog
    qemu_put_8s(f, &s->pins);
3509 aa941b94 balrog
3510 aa941b94 balrog
    qemu_put_8s(f, &s->ctrl);
3511 aa941b94 balrog
    qemu_put_be16s(f, &s->io);
3512 aa941b94 balrog
    qemu_put_byte(f, s->cycle);
3513 aa941b94 balrog
3514 aa941b94 balrog
    drive1_selected = (s->ide->cur_drive != s->ide);
3515 aa941b94 balrog
    qemu_put_8s(f, &s->ide->cmd);
3516 aa941b94 balrog
    qemu_put_8s(f, &drive1_selected);
3517 aa941b94 balrog
3518 aa941b94 balrog
    for (i = 0; i < 2; i ++)
3519 aa941b94 balrog
        ide_save(f, &s->ide[i]);
3520 aa941b94 balrog
}
3521 aa941b94 balrog
3522 aa941b94 balrog
static int md_load(QEMUFile *f, void *opaque, int version_id)
3523 aa941b94 balrog
{
3524 aa941b94 balrog
    struct md_s *s = (struct md_s *) opaque;
3525 aa941b94 balrog
    int i;
3526 aa941b94 balrog
    uint8_t drive1_selected;
3527 aa941b94 balrog
3528 aa941b94 balrog
    qemu_get_8s(f, &s->opt);
3529 aa941b94 balrog
    qemu_get_8s(f, &s->stat);
3530 aa941b94 balrog
    qemu_get_8s(f, &s->pins);
3531 aa941b94 balrog
3532 aa941b94 balrog
    qemu_get_8s(f, &s->ctrl);
3533 aa941b94 balrog
    qemu_get_be16s(f, &s->io);
3534 aa941b94 balrog
    s->cycle = qemu_get_byte(f);
3535 aa941b94 balrog
3536 aa941b94 balrog
    qemu_get_8s(f, &s->ide->cmd);
3537 aa941b94 balrog
    qemu_get_8s(f, &drive1_selected);
3538 aa941b94 balrog
    s->ide->cur_drive = &s->ide[(drive1_selected != 0)];
3539 aa941b94 balrog
3540 aa941b94 balrog
    for (i = 0; i < 2; i ++)
3541 aa941b94 balrog
        ide_load(f, &s->ide[i]);
3542 aa941b94 balrog
3543 aa941b94 balrog
    return 0;
3544 aa941b94 balrog
}
3545 aa941b94 balrog
3546 aa941b94 balrog
static int md_iid = 0;
3547 aa941b94 balrog
3548 201a51fc balrog
static const uint8_t dscm1xxxx_cis[0x14a] = {
3549 201a51fc balrog
    [0x000] = CISTPL_DEVICE,        /* 5V Device Information */
3550 201a51fc balrog
    [0x002] = 0x03,                /* Tuple length = 4 bytes */
3551 201a51fc balrog
    [0x004] = 0xdb,                /* ID: DTYPE_FUNCSPEC, non WP, DSPEED_150NS */
3552 201a51fc balrog
    [0x006] = 0x01,                /* Size = 2K bytes */
3553 201a51fc balrog
    [0x008] = CISTPL_ENDMARK,
3554 201a51fc balrog
3555 201a51fc balrog
    [0x00a] = CISTPL_DEVICE_OC,        /* Additional Device Information */
3556 201a51fc balrog
    [0x00c] = 0x04,                /* Tuple length = 4 byest */
3557 201a51fc balrog
    [0x00e] = 0x03,                /* Conditions: Ext = 0, Vcc 3.3V, MWAIT = 1 */
3558 201a51fc balrog
    [0x010] = 0xdb,                /* ID: DTYPE_FUNCSPEC, non WP, DSPEED_150NS */
3559 201a51fc balrog
    [0x012] = 0x01,                /* Size = 2K bytes */
3560 201a51fc balrog
    [0x014] = CISTPL_ENDMARK,
3561 201a51fc balrog
3562 201a51fc balrog
    [0x016] = CISTPL_JEDEC_C,        /* JEDEC ID */
3563 201a51fc balrog
    [0x018] = 0x02,                /* Tuple length = 2 bytes */
3564 201a51fc balrog
    [0x01a] = 0xdf,                /* PC Card ATA with no Vpp required */
3565 201a51fc balrog
    [0x01c] = 0x01,
3566 201a51fc balrog
3567 201a51fc balrog
    [0x01e] = CISTPL_MANFID,        /* Manufacture ID */
3568 201a51fc balrog
    [0x020] = 0x04,                /* Tuple length = 4 bytes */
3569 201a51fc balrog
    [0x022] = 0xa4,                /* TPLMID_MANF = 00a4 (IBM) */
3570 201a51fc balrog
    [0x024] = 0x00,
3571 201a51fc balrog
    [0x026] = 0x00,                /* PLMID_CARD = 0000 */
3572 201a51fc balrog
    [0x028] = 0x00,
3573 201a51fc balrog
3574 201a51fc balrog
    [0x02a] = CISTPL_VERS_1,        /* Level 1 Version */
3575 201a51fc balrog
    [0x02c] = 0x12,                /* Tuple length = 23 bytes */
3576 201a51fc balrog
    [0x02e] = 0x04,                /* Major Version = JEIDA 4.2 / PCMCIA 2.1 */
3577 201a51fc balrog
    [0x030] = 0x01,                /* Minor Version = 1 */
3578 201a51fc balrog
    [0x032] = 'I',
3579 201a51fc balrog
    [0x034] = 'B',
3580 201a51fc balrog
    [0x036] = 'M',
3581 201a51fc balrog
    [0x038] = 0x00,
3582 201a51fc balrog
    [0x03a] = 'm',
3583 201a51fc balrog
    [0x03c] = 'i',
3584 201a51fc balrog
    [0x03e] = 'c',
3585 201a51fc balrog
    [0x040] = 'r',
3586 201a51fc balrog
    [0x042] = 'o',
3587 201a51fc balrog
    [0x044] = 'd',
3588 201a51fc balrog
    [0x046] = 'r',
3589 201a51fc balrog
    [0x048] = 'i',
3590 201a51fc balrog
    [0x04a] = 'v',
3591 201a51fc balrog
    [0x04c] = 'e',
3592 201a51fc balrog
    [0x04e] = 0x00,
3593 201a51fc balrog
    [0x050] = CISTPL_ENDMARK,
3594 201a51fc balrog
3595 201a51fc balrog
    [0x052] = CISTPL_FUNCID,        /* Function ID */
3596 201a51fc balrog
    [0x054] = 0x02,                /* Tuple length = 2 bytes */
3597 201a51fc balrog
    [0x056] = 0x04,                /* TPLFID_FUNCTION = Fixed Disk */
3598 201a51fc balrog
    [0x058] = 0x01,                /* TPLFID_SYSINIT: POST = 1, ROM = 0 */
3599 201a51fc balrog
3600 201a51fc balrog
    [0x05a] = CISTPL_FUNCE,        /* Function Extension */
3601 201a51fc balrog
    [0x05c] = 0x02,                /* Tuple length = 2 bytes */
3602 201a51fc balrog
    [0x05e] = 0x01,                /* TPLFE_TYPE = Disk Device Interface */
3603 201a51fc balrog
    [0x060] = 0x01,                /* TPLFE_DATA = PC Card ATA Interface */
3604 201a51fc balrog
3605 201a51fc balrog
    [0x062] = CISTPL_FUNCE,        /* Function Extension */
3606 201a51fc balrog
    [0x064] = 0x03,                /* Tuple length = 3 bytes */
3607 201a51fc balrog
    [0x066] = 0x02,                /* TPLFE_TYPE = Basic PC Card ATA Interface */
3608 201a51fc balrog
    [0x068] = 0x08,                /* TPLFE_DATA: Rotating, Unique, Single */
3609 201a51fc balrog
    [0x06a] = 0x0f,                /* TPLFE_DATA: Sleep, Standby, Idle, Auto */
3610 201a51fc balrog
3611 201a51fc balrog
    [0x06c] = CISTPL_CONFIG,        /* Configuration */
3612 201a51fc balrog
    [0x06e] = 0x05,                /* Tuple length = 5 bytes */
3613 201a51fc balrog
    [0x070] = 0x01,                /* TPCC_RASZ = 2 bytes, TPCC_RMSZ = 1 byte */
3614 201a51fc balrog
    [0x072] = 0x07,                /* TPCC_LAST = 7 */
3615 201a51fc balrog
    [0x074] = 0x00,                /* TPCC_RADR = 0200 */
3616 201a51fc balrog
    [0x076] = 0x02,
3617 201a51fc balrog
    [0x078] = 0x0f,                /* TPCC_RMSK = 200, 202, 204, 206 */
3618 201a51fc balrog
3619 201a51fc balrog
    [0x07a] = CISTPL_CFTABLE_ENTRY,        /* 16-bit PC Card Configuration */
3620 201a51fc balrog
    [0x07c] = 0x0b,                /* Tuple length = 11 bytes */
3621 201a51fc balrog
    [0x07e] = 0xc0,                /* TPCE_INDX = Memory Mode, Default, Iface */
3622 201a51fc balrog
    [0x080] = 0xc0,                /* TPCE_IF = Memory, no BVDs, no WP, READY */
3623 201a51fc balrog
    [0x082] = 0xa1,                /* TPCE_FS = Vcc only, no I/O, Memory, Misc */
3624 201a51fc balrog
    [0x084] = 0x27,                /* NomV = 1, MinV = 1, MaxV = 1, Peakl = 1 */
3625 201a51fc balrog
    [0x086] = 0x55,                /* NomV: 5.0 V */
3626 201a51fc balrog
    [0x088] = 0x4d,                /* MinV: 4.5 V */
3627 201a51fc balrog
    [0x08a] = 0x5d,                /* MaxV: 5.5 V */
3628 201a51fc balrog
    [0x08c] = 0x4e,                /* Peakl: 450 mA */
3629 201a51fc balrog
    [0x08e] = 0x08,                /* TPCE_MS = 1 window, 1 byte, Host address */
3630 201a51fc balrog
    [0x090] = 0x00,                /* Window descriptor: Window length = 0 */
3631 201a51fc balrog
    [0x092] = 0x20,                /* TPCE_MI: support power down mode, RW */
3632 201a51fc balrog
3633 201a51fc balrog
    [0x094] = CISTPL_CFTABLE_ENTRY,        /* 16-bit PC Card Configuration */
3634 201a51fc balrog
    [0x096] = 0x06,                /* Tuple length = 6 bytes */
3635 201a51fc balrog
    [0x098] = 0x00,                /* TPCE_INDX = Memory Mode, no Default */
3636 201a51fc balrog
    [0x09a] = 0x01,                /* TPCE_FS = Vcc only, no I/O, no Memory */
3637 201a51fc balrog
    [0x09c] = 0x21,                /* NomV = 1, MinV = 0, MaxV = 0, Peakl = 1 */
3638 201a51fc balrog
    [0x09e] = 0xb5,                /* NomV: 3.3 V */
3639 201a51fc balrog
    [0x0a0] = 0x1e,
3640 201a51fc balrog
    [0x0a2] = 0x3e,                /* Peakl: 350 mA */
3641 201a51fc balrog
3642 201a51fc balrog
    [0x0a4] = CISTPL_CFTABLE_ENTRY,        /* 16-bit PC Card Configuration */
3643 201a51fc balrog
    [0x0a6] = 0x0d,                /* Tuple length = 13 bytes */
3644 201a51fc balrog
    [0x0a8] = 0xc1,                /* TPCE_INDX = I/O and Memory Mode, Default */
3645 201a51fc balrog
    [0x0aa] = 0x41,                /* TPCE_IF = I/O and Memory, no BVD, no WP */
3646 201a51fc balrog
    [0x0ac] = 0x99,                /* TPCE_FS = Vcc only, I/O, Interrupt, Misc */
3647 201a51fc balrog
    [0x0ae] = 0x27,                /* NomV = 1, MinV = 1, MaxV = 1, Peakl = 1 */
3648 201a51fc balrog
    [0x0b0] = 0x55,                /* NomV: 5.0 V */
3649 201a51fc balrog
    [0x0b2] = 0x4d,                /* MinV: 4.5 V */
3650 201a51fc balrog
    [0x0b4] = 0x5d,                /* MaxV: 5.5 V */
3651 201a51fc balrog
    [0x0b6] = 0x4e,                /* Peakl: 450 mA */
3652 201a51fc balrog
    [0x0b8] = 0x64,                /* TPCE_IO = 16-byte boundary, 16/8 accesses */
3653 201a51fc balrog
    [0x0ba] = 0xf0,                /* TPCE_IR =  MASK, Level, Pulse, Share */
3654 201a51fc balrog
    [0x0bc] = 0xff,                /* IRQ0..IRQ7 supported */
3655 201a51fc balrog
    [0x0be] = 0xff,                /* IRQ8..IRQ15 supported */
3656 201a51fc balrog
    [0x0c0] = 0x20,                /* TPCE_MI = support power down mode */
3657 201a51fc balrog
3658 201a51fc balrog
    [0x0c2] = CISTPL_CFTABLE_ENTRY,        /* 16-bit PC Card Configuration */
3659 201a51fc balrog
    [0x0c4] = 0x06,                /* Tuple length = 6 bytes */
3660 201a51fc balrog
    [0x0c6] = 0x01,                /* TPCE_INDX = I/O and Memory Mode */
3661 201a51fc balrog
    [0x0c8] = 0x01,                /* TPCE_FS = Vcc only, no I/O, no Memory */
3662 201a51fc balrog
    [0x0ca] = 0x21,                /* NomV = 1, MinV = 0, MaxV = 0, Peakl = 1 */
3663 201a51fc balrog
    [0x0cc] = 0xb5,                /* NomV: 3.3 V */
3664 201a51fc balrog
    [0x0ce] = 0x1e,
3665 201a51fc balrog
    [0x0d0] = 0x3e,                /* Peakl: 350 mA */
3666 201a51fc balrog
3667 201a51fc balrog
    [0x0d2] = CISTPL_CFTABLE_ENTRY,        /* 16-bit PC Card Configuration */
3668 201a51fc balrog
    [0x0d4] = 0x12,                /* Tuple length = 18 bytes */
3669 201a51fc balrog
    [0x0d6] = 0xc2,                /* TPCE_INDX = I/O Primary Mode */
3670 201a51fc balrog
    [0x0d8] = 0x41,                /* TPCE_IF = I/O and Memory, no BVD, no WP */
3671 201a51fc balrog
    [0x0da] = 0x99,                /* TPCE_FS = Vcc only, I/O, Interrupt, Misc */
3672 201a51fc balrog
    [0x0dc] = 0x27,                /* NomV = 1, MinV = 1, MaxV = 1, Peakl = 1 */
3673 201a51fc balrog
    [0x0de] = 0x55,                /* NomV: 5.0 V */
3674 201a51fc balrog
    [0x0e0] = 0x4d,                /* MinV: 4.5 V */
3675 201a51fc balrog
    [0x0e2] = 0x5d,                /* MaxV: 5.5 V */
3676 201a51fc balrog
    [0x0e4] = 0x4e,                /* Peakl: 450 mA */
3677 201a51fc balrog
    [0x0e6] = 0xea,                /* TPCE_IO = 1K boundary, 16/8 access, Range */
3678 201a51fc balrog
    [0x0e8] = 0x61,                /* Range: 2 fields, 2 bytes addr, 1 byte len */
3679 201a51fc balrog
    [0x0ea] = 0xf0,                /* Field 1 address = 0x01f0 */
3680 201a51fc balrog
    [0x0ec] = 0x01,
3681 201a51fc balrog
    [0x0ee] = 0x07,                /* Address block length = 8 */
3682 201a51fc balrog
    [0x0f0] = 0xf6,                /* Field 2 address = 0x03f6 */
3683 201a51fc balrog
    [0x0f2] = 0x03,
3684 201a51fc balrog
    [0x0f4] = 0x01,                /* Address block length = 2 */
3685 201a51fc balrog
    [0x0f6] = 0xee,                /* TPCE_IR = IRQ E, Level, Pulse, Share */
3686 201a51fc balrog
    [0x0f8] = 0x20,                /* TPCE_MI = support power down mode */
3687 201a51fc balrog
3688 201a51fc balrog
    [0x0fa] = CISTPL_CFTABLE_ENTRY,        /* 16-bit PC Card Configuration */
3689 201a51fc balrog
    [0x0fc] = 0x06,                /* Tuple length = 6 bytes */
3690 201a51fc balrog
    [0x0fe] = 0x02,                /* TPCE_INDX = I/O Primary Mode, no Default */
3691 201a51fc balrog
    [0x100] = 0x01,                /* TPCE_FS = Vcc only, no I/O, no Memory */
3692 201a51fc balrog
    [0x102] = 0x21,                /* NomV = 1, MinV = 0, MaxV = 0, Peakl = 1 */
3693 201a51fc balrog
    [0x104] = 0xb5,                /* NomV: 3.3 V */
3694 201a51fc balrog
    [0x106] = 0x1e,
3695 201a51fc balrog
    [0x108] = 0x3e,                /* Peakl: 350 mA */
3696 201a51fc balrog
3697 201a51fc balrog
    [0x10a] = CISTPL_CFTABLE_ENTRY,        /* 16-bit PC Card Configuration */
3698 201a51fc balrog
    [0x10c] = 0x12,                /* Tuple length = 18 bytes */
3699 201a51fc balrog
    [0x10e] = 0xc3,                /* TPCE_INDX = I/O Secondary Mode, Default */
3700 201a51fc balrog
    [0x110] = 0x41,                /* TPCE_IF = I/O and Memory, no BVD, no WP */
3701 201a51fc balrog
    [0x112] = 0x99,                /* TPCE_FS = Vcc only, I/O, Interrupt, Misc */
3702 201a51fc balrog
    [0x114] = 0x27,                /* NomV = 1, MinV = 1, MaxV = 1, Peakl = 1 */
3703 201a51fc balrog
    [0x116] = 0x55,                /* NomV: 5.0 V */
3704 201a51fc balrog
    [0x118] = 0x4d,                /* MinV: 4.5 V */
3705 201a51fc balrog
    [0x11a] = 0x5d,                /* MaxV: 5.5 V */
3706 201a51fc balrog
    [0x11c] = 0x4e,                /* Peakl: 450 mA */
3707 201a51fc balrog
    [0x11e] = 0xea,                /* TPCE_IO = 1K boundary, 16/8 access, Range */
3708 201a51fc balrog
    [0x120] = 0x61,                /* Range: 2 fields, 2 byte addr, 1 byte len */
3709 201a51fc balrog
    [0x122] = 0x70,                /* Field 1 address = 0x0170 */
3710 201a51fc balrog
    [0x124] = 0x01,
3711 201a51fc balrog
    [0x126] = 0x07,                /* Address block length = 8 */
3712 201a51fc balrog
    [0x128] = 0x76,                /* Field 2 address = 0x0376 */
3713 201a51fc balrog
    [0x12a] = 0x03,
3714 201a51fc balrog
    [0x12c] = 0x01,                /* Address block length = 2 */
3715 201a51fc balrog
    [0x12e] = 0xee,                /* TPCE_IR = IRQ E, Level, Pulse, Share */
3716 201a51fc balrog
    [0x130] = 0x20,                /* TPCE_MI = support power down mode */
3717 201a51fc balrog
3718 201a51fc balrog
    [0x132] = CISTPL_CFTABLE_ENTRY,        /* 16-bit PC Card Configuration */
3719 201a51fc balrog
    [0x134] = 0x06,                /* Tuple length = 6 bytes */
3720 201a51fc balrog
    [0x136] = 0x03,                /* TPCE_INDX = I/O Secondary Mode */
3721 201a51fc balrog
    [0x138] = 0x01,                /* TPCE_FS = Vcc only, no I/O, no Memory */
3722 201a51fc balrog
    [0x13a] = 0x21,                /* NomV = 1, MinV = 0, MaxV = 0, Peakl = 1 */
3723 201a51fc balrog
    [0x13c] = 0xb5,                /* NomV: 3.3 V */
3724 201a51fc balrog
    [0x13e] = 0x1e,
3725 201a51fc balrog
    [0x140] = 0x3e,                /* Peakl: 350 mA */
3726 201a51fc balrog
3727 201a51fc balrog
    [0x142] = CISTPL_NO_LINK,        /* No Link */
3728 201a51fc balrog
    [0x144] = 0x00,                /* Tuple length = 0 bytes */
3729 201a51fc balrog
3730 201a51fc balrog
    [0x146] = CISTPL_END,        /* Tuple End */
3731 201a51fc balrog
};
3732 201a51fc balrog
3733 201a51fc balrog
static int dscm1xxxx_attach(void *opaque)
3734 201a51fc balrog
{
3735 201a51fc balrog
    struct md_s *md = (struct md_s *) opaque;
3736 201a51fc balrog
    md->card.attr_read = md_attr_read;
3737 201a51fc balrog
    md->card.attr_write = md_attr_write;
3738 201a51fc balrog
    md->card.common_read = md_common_read;
3739 201a51fc balrog
    md->card.common_write = md_common_write;
3740 201a51fc balrog
    md->card.io_read = md_common_read;
3741 201a51fc balrog
    md->card.io_write = md_common_write;
3742 201a51fc balrog
3743 201a51fc balrog
    md->attr_base = md->card.cis[0x74] | (md->card.cis[0x76] << 8);
3744 201a51fc balrog
    md->io_base = 0x0;
3745 201a51fc balrog
3746 201a51fc balrog
    md_reset(md);
3747 201a51fc balrog
    md_interrupt_update(md);
3748 201a51fc balrog
3749 201a51fc balrog
    md->card.slot->card_string = "DSCM-1xxxx Hitachi Microdrive";
3750 201a51fc balrog
    return 0;
3751 201a51fc balrog
}
3752 201a51fc balrog
3753 201a51fc balrog
static int dscm1xxxx_detach(void *opaque)
3754 201a51fc balrog
{
3755 201a51fc balrog
    struct md_s *md = (struct md_s *) opaque;
3756 201a51fc balrog
    md_reset(md);
3757 201a51fc balrog
    return 0;
3758 201a51fc balrog
}
3759 201a51fc balrog
3760 201a51fc balrog
struct pcmcia_card_s *dscm1xxxx_init(BlockDriverState *bdrv)
3761 201a51fc balrog
{
3762 201a51fc balrog
    struct md_s *md = (struct md_s *) qemu_mallocz(sizeof(struct md_s));
3763 201a51fc balrog
    md->card.state = md;
3764 201a51fc balrog
    md->card.attach = dscm1xxxx_attach;
3765 201a51fc balrog
    md->card.detach = dscm1xxxx_detach;
3766 201a51fc balrog
    md->card.cis = dscm1xxxx_cis;
3767 201a51fc balrog
    md->card.cis_len = sizeof(dscm1xxxx_cis);
3768 201a51fc balrog
3769 201a51fc balrog
    ide_init2(md->ide, bdrv, 0, qemu_allocate_irqs(md_set_irq, md, 1)[0]);
3770 201a51fc balrog
    md->ide->is_cf = 1;
3771 201a51fc balrog
    md->ide->mdata_size = METADATA_SIZE;
3772 201a51fc balrog
    md->ide->mdata_storage = (uint8_t *) qemu_mallocz(METADATA_SIZE);
3773 aa941b94 balrog
3774 aa941b94 balrog
    register_savevm("microdrive", md_iid ++, 0, md_save, md_load, md);
3775 aa941b94 balrog
3776 201a51fc balrog
    return &md->card;
3777 201a51fc balrog
}