Statistics
| Branch: | Revision:

root / hw / ide.c @ cd08ce8f

History | View | Annotate | Download (110.8 kB)

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