Statistics
| Branch: | Revision:

root / hw / ide.c @ a8a358bf

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