Statistics
| Branch: | Revision:

root / hw / ide.c @ b8c18e4c

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