Commit caed880216f3572b5f33691f46c934e1d0faccb2

Authored by bellard
1 parent b338082b

removable device support - io port API change


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@659 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 151 additions and 153 deletions
hw/fdc.c
... ... @@ -85,12 +85,14 @@ typedef struct fdrive_t {
85 85 uint8_t ro; /* Is read-only */
86 86 } fdrive_t;
87 87  
88   -static void fd_init (fdrive_t *drv)
  88 +static void fd_init (fdrive_t *drv, BlockDriverState *bs)
89 89 {
90 90 /* Drive */
91   - drv->bs = NULL;
92   -// drv->drive = FDRIVE_DRV_288;
93   - drv->drive = FDRIVE_DRV_144;
  91 + drv->bs = bs;
  92 + if (bs)
  93 + drv->drive = FDRIVE_DRV_144;
  94 + else
  95 + drv->drive = FDRIVE_DRV_NONE;
94 96 drv->motor = 0;
95 97 drv->perpendicular = 0;
96 98 drv->rv = 0;
... ... @@ -157,13 +159,17 @@ static void fd_recalibrate (fdrive_t *drv)
157 159 }
158 160  
159 161 /* Revalidate a disk drive after a disk change */
160   -static void fd_revalidate (fdrive_t *drv, int ro)
  162 +static void fd_revalidate (fdrive_t *drv)
161 163 {
162 164 int64_t nb_sectors;
163 165  
164 166 FLOPPY_DPRINTF("revalidate\n");
165 167 drv->rv = 0;
166   - if (drv->bs != NULL) {
  168 + /* if no drive present, cannot do more */
  169 + if (!drv->bs)
  170 + return;
  171 +
  172 + if (bdrv_is_inserted(drv->bs)) {
167 173 bdrv_get_geometry(drv->bs, &nb_sectors);
168 174 #if 1
169 175 if (nb_sectors > 2880)
... ... @@ -186,14 +192,21 @@ static void fd_revalidate (fdrive_t *drv, int ro)
186 192 drv->max_track = 80;
187 193 #endif
188 194 }
  195 + drv->ro = bdrv_is_read_only(drv->bs);
189 196 } else {
190 197 drv->disk = FDRIVE_DISK_NONE;
191 198 drv->last_sect = 1; /* Avoid eventual divide by 0 bugs */
  199 + drv->ro = 0;
192 200 }
193   - drv->ro = ro;
194 201 drv->rv = 1;
195 202 }
196 203  
  204 +static void fd_change_cb (void *opaque)
  205 +{
  206 + fdrive_t *drv = opaque;
  207 + fd_revalidate(drv);
  208 +}
  209 +
197 210 /* Motor control */
198 211 static void fd_start (fdrive_t *drv)
199 212 {
... ... @@ -220,16 +233,16 @@ static void fdctrl_reset_fifo (void);
220 233 static int fdctrl_transfer_handler (void *opaque, target_ulong addr, int size);
221 234 static void fdctrl_raise_irq (uint8_t status);
222 235  
223   -static uint32_t fdctrl_read_statusB (CPUState *env, uint32_t reg);
224   -static uint32_t fdctrl_read_dor (CPUState *env, uint32_t reg);
225   -static void fdctrl_write_dor (CPUState *env, uint32_t reg, uint32_t value);
226   -static uint32_t fdctrl_read_tape (CPUState *env, uint32_t reg);
227   -static void fdctrl_write_tape (CPUState *env, uint32_t reg, uint32_t value);
228   -static uint32_t fdctrl_read_main_status (CPUState *env, uint32_t reg);
229   -static void fdctrl_write_rate (CPUState *env, uint32_t reg, uint32_t value);
230   -static uint32_t fdctrl_read_data (CPUState *env, uint32_t reg);
231   -static void fdctrl_write_data (CPUState *env, uint32_t reg, uint32_t value);
232   -static uint32_t fdctrl_read_dir (CPUState *env, uint32_t reg);
  236 +static uint32_t fdctrl_read_statusB (void *opaque, uint32_t reg);
  237 +static uint32_t fdctrl_read_dor (void *opaque, uint32_t reg);
  238 +static void fdctrl_write_dor (void *opaque, uint32_t reg, uint32_t value);
  239 +static uint32_t fdctrl_read_tape (void *opaque, uint32_t reg);
  240 +static void fdctrl_write_tape (void *opaque, uint32_t reg, uint32_t value);
  241 +static uint32_t fdctrl_read_main_status (void *opaque, uint32_t reg);
  242 +static void fdctrl_write_rate (void *opaque, uint32_t reg, uint32_t value);
  243 +static uint32_t fdctrl_read_data (void *opaque, uint32_t reg);
  244 +static void fdctrl_write_data (void *opaque, uint32_t reg, uint32_t value);
  245 +static uint32_t fdctrl_read_dir (void *opaque, uint32_t reg);
233 246  
234 247 enum {
235 248 FD_CTRL_ACTIVE = 0x01,
... ... @@ -295,7 +308,7 @@ typedef struct fdctrl_t {
295 308 static fdctrl_t fdctrl;
296 309  
297 310 void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base,
298   - char boot_device)
  311 + BlockDriverState **fds)
299 312 {
300 313 // int io_mem;
301 314 int i;
... ... @@ -312,8 +325,11 @@ void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base,
312 325 } else {
313 326 fdctrl.dma_en = 0;
314 327 }
315   - for (i = 0; i < MAX_FD; i++)
316   - fd_init(&fdctrl.drives[i]);
  328 + for (i = 0; i < MAX_FD; i++) {
  329 + fd_init(&fdctrl.drives[i], fds[i]);
  330 + if (fds[i])
  331 + bdrv_set_change_cb(fds[i], fd_change_cb, &fdctrl.drives[i]);
  332 + }
317 333 fdctrl_reset(0);
318 334 fdctrl.state = FD_CTRL_ACTIVE;
319 335 if (mem_mapped) {
... ... @@ -323,51 +339,27 @@ void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base,
323 339 cpu_register_physical_memory(base, 0x08, io_mem);
324 340 #endif
325 341 } else {
326   - register_ioport_read(base + 0x01, 1, fdctrl_read_statusB, 1);
327   - register_ioport_read(base + 0x02, 1, fdctrl_read_dor, 1);
328   - register_ioport_write(base + 0x02, 1, fdctrl_write_dor, 1);
329   - register_ioport_read(base + 0x03, 1, fdctrl_read_tape, 1);
330   - register_ioport_write(base + 0x03, 1, fdctrl_write_tape, 1);
331   - register_ioport_read(base + 0x04, 1, fdctrl_read_main_status, 1);
332   - register_ioport_write(base + 0x04, 1, fdctrl_write_rate, 1);
333   - register_ioport_read(base + 0x05, 1, fdctrl_read_data, 1);
334   - register_ioport_write(base + 0x05, 1, fdctrl_write_data, 1);
335   - register_ioport_read(base + 0x07, 1, fdctrl_read_dir, 1);
  342 + register_ioport_read(base + 0x01, 1, 1, fdctrl_read_statusB, NULL);
  343 + register_ioport_read(base + 0x02, 1, 1, fdctrl_read_dor, NULL);
  344 + register_ioport_write(base + 0x02, 1, 1, fdctrl_write_dor, NULL);
  345 + register_ioport_read(base + 0x03, 1, 1, fdctrl_read_tape, NULL);
  346 + register_ioport_write(base + 0x03, 1, 1, fdctrl_write_tape, NULL);
  347 + register_ioport_read(base + 0x04, 1, 1, fdctrl_read_main_status, NULL);
  348 + register_ioport_write(base + 0x04, 1, 1, fdctrl_write_rate, NULL);
  349 + register_ioport_read(base + 0x05, 1, 1, fdctrl_read_data, NULL);
  350 + register_ioport_write(base + 0x05, 1, 1, fdctrl_write_data, NULL);
  351 + register_ioport_read(base + 0x07, 1, 1, fdctrl_read_dir, NULL);
336 352 }
337   - if (boot_device == 'b')
338   - fdctrl.bootsel = 1;
339   - else
340   - fdctrl.bootsel = 0;
341   -#if defined (TARGET_I386)
342   - cmos_register_fd(fdctrl.drives[0].drive, fdctrl.drives[1].drive);
343   -#endif
344   -}
345   -
346   -int fdctrl_disk_change (int idx, const unsigned char *filename, int ro)
347   -{
348   - fdrive_t *drv;
  353 + fdctrl.bootsel = 0;
349 354  
350   - if (idx < 0 || idx > 1)
351   - return -1;
352   - FLOPPY_DPRINTF("disk %d change: %s (%s)\n", idx, filename,
353   - ro == 0 ? "rw" : "ro");
354   - drv = &fdctrl.drives[idx];
355   - if (fd_table[idx] != NULL) {
356   - bdrv_close(fd_table[idx]);
357   - fd_table[idx] = NULL;
  355 + for (i = 0; i < MAX_FD; i++) {
  356 + fd_revalidate(&fdctrl.drives[i]);
358 357 }
359   - fd_table[idx] = bdrv_open(filename, ro);
360   - drv->bs = fd_table[idx];
361   - if (fd_table[idx] == NULL)
362   - return -1;
363   - fd_revalidate(drv, ro);
364   -#if 0
365   - fd_recalibrate(drv);
366   - fdctrl_reset_fifo();
367   - fdctrl_raise_irq(0x20);
368   -#endif
  358 +}
369 359  
370   - return 0;
  360 +int fdctrl_get_drive_type(int drive_num)
  361 +{
  362 + return fdctrl.drives[drive_num].drive;
371 363 }
372 364  
373 365 /* Change IRQ state */
... ... @@ -411,7 +403,7 @@ static void fdctrl_reset (int do_irq)
411 403 }
412 404  
413 405 /* Status B register : 0x01 (read-only) */
414   -static uint32_t fdctrl_read_statusB (CPUState *env, uint32_t reg)
  406 +static uint32_t fdctrl_read_statusB (void *opaque, uint32_t reg)
415 407 {
416 408 fdctrl_reset_irq();
417 409 FLOPPY_DPRINTF("status register: 0x00\n");
... ... @@ -420,7 +412,7 @@ static uint32_t fdctrl_read_statusB (CPUState *env, uint32_t reg)
420 412 }
421 413  
422 414 /* Digital output register : 0x02 */
423   -static uint32_t fdctrl_read_dor (CPUState *env, uint32_t reg)
  415 +static uint32_t fdctrl_read_dor (void *opaque, uint32_t reg)
424 416 {
425 417 fdrive_t *cur_drv, *drv0, *drv1;
426 418 uint32_t retval = 0;
... ... @@ -442,7 +434,7 @@ static uint32_t fdctrl_read_dor (CPUState *env, uint32_t reg)
442 434 return retval;
443 435 }
444 436  
445   -static void fdctrl_write_dor (CPUState *env, uint32_t reg, uint32_t value)
  437 +static void fdctrl_write_dor (void *opaque, uint32_t reg, uint32_t value)
446 438 {
447 439 fdrive_t *drv0, *drv1;
448 440  
... ... @@ -489,7 +481,7 @@ static void fdctrl_write_dor (CPUState *env, uint32_t reg, uint32_t value)
489 481 }
490 482  
491 483 /* Tape drive register : 0x03 */
492   -static uint32_t fdctrl_read_tape (CPUState *env, uint32_t reg)
  484 +static uint32_t fdctrl_read_tape (void *opaque, uint32_t reg)
493 485 {
494 486 uint32_t retval = 0;
495 487  
... ... @@ -502,7 +494,7 @@ static uint32_t fdctrl_read_tape (CPUState *env, uint32_t reg)
502 494 return retval;
503 495 }
504 496  
505   -static void fdctrl_write_tape (CPUState *env, uint32_t reg, uint32_t value)
  497 +static void fdctrl_write_tape (void *opaque, uint32_t reg, uint32_t value)
506 498 {
507 499 fdctrl_reset_irq();
508 500 /* Reset mode */
... ... @@ -517,7 +509,7 @@ static void fdctrl_write_tape (CPUState *env, uint32_t reg, uint32_t value)
517 509 }
518 510  
519 511 /* Main status register : 0x04 (read) */
520   -static uint32_t fdctrl_read_main_status (CPUState *env, uint32_t reg)
  512 +static uint32_t fdctrl_read_main_status (void *opaque, uint32_t reg)
521 513 {
522 514 uint32_t retval = 0;
523 515  
... ... @@ -541,7 +533,7 @@ static uint32_t fdctrl_read_main_status (CPUState *env, uint32_t reg)
541 533 }
542 534  
543 535 /* Data select rate register : 0x04 (write) */
544   -static void fdctrl_write_rate (CPUState *env, uint32_t reg, uint32_t value)
  536 +static void fdctrl_write_rate (void *opaque, uint32_t reg, uint32_t value)
545 537 {
546 538 fdctrl_reset_irq();
547 539 /* Reset mode */
... ... @@ -566,7 +558,7 @@ static void fdctrl_write_rate (CPUState *env, uint32_t reg, uint32_t value)
566 558 }
567 559  
568 560 /* Digital input register : 0x07 (read-only) */
569   -static uint32_t fdctrl_read_dir (CPUState *env, uint32_t reg)
  561 +static uint32_t fdctrl_read_dir (void *opaque, uint32_t reg)
570 562 {
571 563 fdrive_t *drv0, *drv1;
572 564 uint32_t retval = 0;
... ... @@ -872,7 +864,7 @@ transfer_error:
872 864 }
873 865  
874 866 /* Data register : 0x05 */
875   -static uint32_t fdctrl_read_data (CPUState *env, uint32_t reg)
  867 +static uint32_t fdctrl_read_data (void *opaque, uint32_t reg)
876 868 {
877 869 fdrive_t *cur_drv, *drv0, *drv1;
878 870 uint32_t retval = 0;
... ... @@ -914,7 +906,7 @@ static uint32_t fdctrl_read_data (CPUState *env, uint32_t reg)
914 906 return retval;
915 907 }
916 908  
917   -static void fdctrl_write_data (CPUState *env, uint32_t reg, uint32_t value)
  909 +static void fdctrl_write_data (void *opaque, uint32_t reg, uint32_t value)
918 910 {
919 911 fdrive_t *cur_drv, *drv0, *drv1;
920 912  
... ...
hw/ide.c
... ... @@ -314,10 +314,10 @@ struct IDEState;
314 314  
315 315 typedef void EndTransferFunc(struct IDEState *);
316 316  
  317 +/* NOTE: IDEState represents in fact one drive */
317 318 typedef struct IDEState {
318 319 /* ide config */
319 320 int is_cdrom;
320   - int cdrom_locked;
321 321 int cylinders, heads, sectors;
322 322 int64_t nb_sectors;
323 323 int mult_sectors;
... ... @@ -351,14 +351,6 @@ typedef struct IDEState {
351 351 uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
352 352 } IDEState;
353 353  
354   -IDEState ide_state[MAX_DISKS];
355   -IDEState *ide_table[0x400 >> 3];
356   -
357   -static inline IDEState *get_ide_interface(uint32_t addr)
358   -{
359   - return ide_table[addr >> 3];
360   -}
361   -
362 354 static void padstr(char *str, const char *src, int len)
363 355 {
364 356 int i, v;
... ... @@ -815,7 +807,7 @@ static void ide_atapi_cmd(IDEState *s)
815 807 #endif
816 808 switch(s->io_buffer[0]) {
817 809 case GPCMD_TEST_UNIT_READY:
818   - if (s->bs) {
  810 + if (bdrv_is_inserted(s->bs)) {
819 811 ide_atapi_cmd_ok(s);
820 812 } else {
821 813 ide_atapi_cmd_error(s, SENSE_NOT_READY,
... ... @@ -867,7 +859,7 @@ static void ide_atapi_cmd(IDEState *s)
867 859 buf[12] = 0x70;
868 860 buf[13] = 3 << 5;
869 861 buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
870   - if (s->cdrom_locked)
  862 + if (bdrv_is_locked(s->bs))
871 863 buf[6] |= 1 << 1;
872 864 buf[15] = 0x00;
873 865 cpu_to_ube16(&buf[16], 706);
... ... @@ -907,8 +899,8 @@ static void ide_atapi_cmd(IDEState *s)
907 899 ide_atapi_cmd_reply(s, 18, max_len);
908 900 break;
909 901 case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
910   - if (s->bs) {
911   - s->cdrom_locked = packet[4] & 1;
  902 + if (bdrv_is_inserted(s->bs)) {
  903 + bdrv_set_locked(s->bs, packet[4] & 1);
912 904 ide_atapi_cmd_ok(s);
913 905 } else {
914 906 ide_atapi_cmd_error(s, SENSE_NOT_READY,
... ... @@ -920,7 +912,7 @@ static void ide_atapi_cmd(IDEState *s)
920 912 {
921 913 int nb_sectors, lba;
922 914  
923   - if (!s->bs) {
  915 + if (!bdrv_is_inserted(s->bs)) {
924 916 ide_atapi_cmd_error(s, SENSE_NOT_READY,
925 917 ASC_MEDIUM_NOT_PRESENT);
926 918 break;
... ... @@ -945,7 +937,7 @@ static void ide_atapi_cmd(IDEState *s)
945 937 case GPCMD_SEEK:
946 938 {
947 939 int lba;
948   - if (!s->bs) {
  940 + if (!bdrv_is_inserted(s->bs)) {
949 941 ide_atapi_cmd_error(s, SENSE_NOT_READY,
950 942 ASC_MEDIUM_NOT_PRESENT);
951 943 break;
... ... @@ -965,7 +957,10 @@ static void ide_atapi_cmd(IDEState *s)
965 957 start = packet[4] & 1;
966 958 eject = (packet[4] >> 1) & 1;
967 959  
968   - /* XXX: currently none implemented */
  960 + if (eject && !start) {
  961 + /* eject the disk */
  962 + bdrv_close(s->bs);
  963 + }
969 964 ide_atapi_cmd_ok(s);
970 965 }
971 966 break;
... ... @@ -986,7 +981,7 @@ static void ide_atapi_cmd(IDEState *s)
986 981 {
987 982 int format, msf, start_track, len;
988 983  
989   - if (!s->bs) {
  984 + if (!bdrv_is_inserted(s->bs)) {
990 985 ide_atapi_cmd_error(s, SENSE_NOT_READY,
991 986 ASC_MEDIUM_NOT_PRESENT);
992 987 break;
... ... @@ -1019,7 +1014,7 @@ static void ide_atapi_cmd(IDEState *s)
1019 1014 }
1020 1015 break;
1021 1016 case GPCMD_READ_CDVD_CAPACITY:
1022   - if (!s->bs) {
  1017 + if (!bdrv_is_inserted(s->bs)) {
1023 1018 ide_atapi_cmd_error(s, SENSE_NOT_READY,
1024 1019 ASC_MEDIUM_NOT_PRESENT);
1025 1020 break;
... ... @@ -1051,9 +1046,20 @@ static void ide_atapi_cmd(IDEState *s)
1051 1046 }
1052 1047 }
1053 1048  
1054   -static void ide_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
  1049 +/* called when the inserted state of the media has changed */
  1050 +static void cdrom_change_cb(void *opaque)
1055 1051 {
1056   - IDEState *ide_if = get_ide_interface(addr);
  1052 + IDEState *s = opaque;
  1053 + int64_t nb_sectors;
  1054 +
  1055 + /* XXX: send interrupt too */
  1056 + bdrv_get_geometry(s->bs, &nb_sectors);
  1057 + s->nb_sectors = nb_sectors;
  1058 +}
  1059 +
  1060 +static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
  1061 +{
  1062 + IDEState *ide_if = opaque;
1057 1063 IDEState *s = ide_if->cur_drive;
1058 1064 int unit, n;
1059 1065  
... ... @@ -1210,9 +1216,9 @@ static void ide_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
1210 1216 }
1211 1217 }
1212 1218  
1213   -static uint32_t ide_ioport_read(CPUState *env, uint32_t addr1)
  1219 +static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
1214 1220 {
1215   - IDEState *s = get_ide_interface(addr1)->cur_drive;
  1221 + IDEState *s = ((IDEState *)opaque)->cur_drive;
1216 1222 uint32_t addr;
1217 1223 int ret;
1218 1224  
... ... @@ -1251,9 +1257,9 @@ static uint32_t ide_ioport_read(CPUState *env, uint32_t addr1)
1251 1257 return ret;
1252 1258 }
1253 1259  
1254   -static uint32_t ide_status_read(CPUState *env, uint32_t addr)
  1260 +static uint32_t ide_status_read(void *opaque, uint32_t addr)
1255 1261 {
1256   - IDEState *s = get_ide_interface(addr)->cur_drive;
  1262 + IDEState *s = ((IDEState *)opaque)->cur_drive;
1257 1263 int ret;
1258 1264 ret = s->status;
1259 1265 #ifdef DEBUG_IDE
... ... @@ -1262,9 +1268,9 @@ static uint32_t ide_status_read(CPUState *env, uint32_t addr)
1262 1268 return ret;
1263 1269 }
1264 1270  
1265   -static void ide_cmd_write(CPUState *env, uint32_t addr, uint32_t val)
  1271 +static void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
1266 1272 {
1267   - IDEState *ide_if = get_ide_interface(addr);
  1273 + IDEState *ide_if = opaque;
1268 1274 IDEState *s;
1269 1275 int i;
1270 1276  
... ... @@ -1297,9 +1303,9 @@ static void ide_cmd_write(CPUState *env, uint32_t addr, uint32_t val)
1297 1303 ide_if[1].cmd = val;
1298 1304 }
1299 1305  
1300   -static void ide_data_writew(CPUState *env, uint32_t addr, uint32_t val)
  1306 +static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
1301 1307 {
1302   - IDEState *s = get_ide_interface(addr)->cur_drive;
  1308 + IDEState *s = ((IDEState *)opaque)->cur_drive;
1303 1309 uint8_t *p;
1304 1310  
1305 1311 p = s->data_ptr;
... ... @@ -1310,9 +1316,9 @@ static void ide_data_writew(CPUState *env, uint32_t addr, uint32_t val)
1310 1316 s->end_transfer_func(s);
1311 1317 }
1312 1318  
1313   -static uint32_t ide_data_readw(CPUState *env, uint32_t addr)
  1319 +static uint32_t ide_data_readw(void *opaque, uint32_t addr)
1314 1320 {
1315   - IDEState *s = get_ide_interface(addr)->cur_drive;
  1321 + IDEState *s = ((IDEState *)opaque)->cur_drive;
1316 1322 uint8_t *p;
1317 1323 int ret;
1318 1324 p = s->data_ptr;
... ... @@ -1324,9 +1330,9 @@ static uint32_t ide_data_readw(CPUState *env, uint32_t addr)
1324 1330 return ret;
1325 1331 }
1326 1332  
1327   -static void ide_data_writel(CPUState *env, uint32_t addr, uint32_t val)
  1333 +static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
1328 1334 {
1329   - IDEState *s = get_ide_interface(addr)->cur_drive;
  1335 + IDEState *s = ((IDEState *)opaque)->cur_drive;
1330 1336 uint8_t *p;
1331 1337  
1332 1338 p = s->data_ptr;
... ... @@ -1337,9 +1343,9 @@ static void ide_data_writel(CPUState *env, uint32_t addr, uint32_t val)
1337 1343 s->end_transfer_func(s);
1338 1344 }
1339 1345  
1340   -static uint32_t ide_data_readl(CPUState *env, uint32_t addr)
  1346 +static uint32_t ide_data_readl(void *opaque, uint32_t addr)
1341 1347 {
1342   - IDEState *s = get_ide_interface(addr)->cur_drive;
  1348 + IDEState *s = ((IDEState *)opaque)->cur_drive;
1343 1349 uint8_t *p;
1344 1350 int ret;
1345 1351  
... ... @@ -1407,64 +1413,64 @@ static void ide_guess_geometry(IDEState *s)
1407 1413 }
1408 1414 }
1409 1415  
1410   -void ide_init(void)
  1416 +void ide_init(int iobase, int iobase2, int irq,
  1417 + BlockDriverState *hd0, BlockDriverState *hd1)
1411 1418 {
1412   - IDEState *s;
1413   - int i, cylinders, iobase, iobase2;
  1419 + IDEState *s, *ide_state;
  1420 + int i, cylinders, heads, secs;
1414 1421 int64_t nb_sectors;
1415   - static const int ide_iobase[2] = { 0x1f0, 0x170 };
1416   - static const int ide_iobase2[2] = { 0x3f6, 0x376 };
1417   - static const int ide_irq[2] = { 14, 15 };
1418 1422  
1419   - for(i = 0; i < MAX_DISKS; i++) {
1420   - s = &ide_state[i];
1421   - s->bs = bs_table[i];
  1423 + ide_state = qemu_mallocz(sizeof(IDEState) * 2);
  1424 + if (!ide_state)
  1425 + return;
  1426 +
  1427 + for(i = 0; i < 2; i++) {
  1428 + s = ide_state + i;
  1429 + if (i == 0)
  1430 + s->bs = hd0;
  1431 + else
  1432 + s->bs = hd1;
1422 1433 if (s->bs) {
1423 1434 bdrv_get_geometry(s->bs, &nb_sectors);
1424 1435 s->nb_sectors = nb_sectors;
1425   - ide_guess_geometry(s);
1426   - if (s->cylinders == 0) {
1427   - /* if no geometry, use a LBA compatible one */
1428   - cylinders = nb_sectors / (16 * 63);
1429   - if (cylinders > 16383)
1430   - cylinders = 16383;
1431   - else if (cylinders < 2)
1432   - cylinders = 2;
  1436 + /* if a geometry hint is available, use it */
  1437 + bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
  1438 + if (cylinders != 0) {
1433 1439 s->cylinders = cylinders;
1434   - s->heads = 16;
1435   - s->sectors = 63;
  1440 + s->heads = heads;
  1441 + s->sectors = secs;
  1442 + } else {
  1443 + ide_guess_geometry(s);
  1444 + if (s->cylinders == 0) {
  1445 + /* if no geometry, use a LBA compatible one */
  1446 + cylinders = nb_sectors / (16 * 63);
  1447 + if (cylinders > 16383)
  1448 + cylinders = 16383;
  1449 + else if (cylinders < 2)
  1450 + cylinders = 2;
  1451 + s->cylinders = cylinders;
  1452 + s->heads = 16;
  1453 + s->sectors = 63;
  1454 + }
  1455 + }
  1456 + if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
  1457 + s->is_cdrom = 1;
  1458 + bdrv_set_change_cb(s->bs, cdrom_change_cb, s);
1436 1459 }
1437 1460 }
1438   - s->irq = ide_irq[i >> 1];
  1461 + s->irq = irq;
1439 1462 ide_reset(s);
1440 1463 }
1441   - for(i = 0; i < (MAX_DISKS / 2); i++) {
1442   - iobase = ide_iobase[i];
1443   - iobase2 = ide_iobase2[i];
1444   - ide_table[iobase >> 3] = &ide_state[2 * i];
1445   - if (ide_iobase2[i])
1446   - ide_table[iobase2 >> 3] = &ide_state[2 * i];
1447   - register_ioport_write(iobase, 8, ide_ioport_write, 1);
1448   - register_ioport_read(iobase, 8, ide_ioport_read, 1);
1449   - register_ioport_read(iobase2, 1, ide_status_read, 1);
1450   - register_ioport_write(iobase2, 1, ide_cmd_write, 1);
1451   -
1452   - /* data ports */
1453   - register_ioport_write(iobase, 2, ide_data_writew, 2);
1454   - register_ioport_read(iobase, 2, ide_data_readw, 2);
1455   - register_ioport_write(iobase, 4, ide_data_writel, 4);
1456   - register_ioport_read(iobase, 4, ide_data_readl, 4);
  1464 + register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state);
  1465 + register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state);
  1466 + if (iobase2) {
  1467 + register_ioport_read(iobase2, 1, 1, ide_status_read, ide_state);
  1468 + register_ioport_write(iobase2, 1, 1, ide_cmd_write, ide_state);
1457 1469 }
1458   -}
1459   -
1460   -void ide_set_geometry(int n, int cyls, int heads, int secs)
1461   -{
1462   - ide_state[n].cylinders = cyls;
1463   - ide_state[n].heads = heads;
1464   - ide_state[n].sectors = secs;
1465   -}
1466   -
1467   -void ide_set_cdrom(int n, int is_cdrom)
1468   -{
1469   - ide_state[n].is_cdrom = is_cdrom;
  1470 +
  1471 + /* data ports */
  1472 + register_ioport_write(iobase, 2, 2, ide_data_writew, ide_state);
  1473 + register_ioport_read(iobase, 2, 2, ide_data_readw, ide_state);
  1474 + register_ioport_write(iobase, 4, 4, ide_data_writel, ide_state);
  1475 + register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state);
1470 1476 }
... ...