Statistics
| Branch: | Revision:

root / hw / ide.c @ d94f9486

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