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,12 +85,14 @@ typedef struct fdrive_t {
85 uint8_t ro; /* Is read-only */ 85 uint8_t ro; /* Is read-only */
86 } fdrive_t; 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 /* Drive */ 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 drv->motor = 0; 96 drv->motor = 0;
95 drv->perpendicular = 0; 97 drv->perpendicular = 0;
96 drv->rv = 0; 98 drv->rv = 0;
@@ -157,13 +159,17 @@ static void fd_recalibrate (fdrive_t *drv) @@ -157,13 +159,17 @@ static void fd_recalibrate (fdrive_t *drv)
157 } 159 }
158 160
159 /* Revalidate a disk drive after a disk change */ 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 int64_t nb_sectors; 164 int64_t nb_sectors;
163 165
164 FLOPPY_DPRINTF("revalidate\n"); 166 FLOPPY_DPRINTF("revalidate\n");
165 drv->rv = 0; 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 bdrv_get_geometry(drv->bs, &nb_sectors); 173 bdrv_get_geometry(drv->bs, &nb_sectors);
168 #if 1 174 #if 1
169 if (nb_sectors > 2880) 175 if (nb_sectors > 2880)
@@ -186,14 +192,21 @@ static void fd_revalidate (fdrive_t *drv, int ro) @@ -186,14 +192,21 @@ static void fd_revalidate (fdrive_t *drv, int ro)
186 drv->max_track = 80; 192 drv->max_track = 80;
187 #endif 193 #endif
188 } 194 }
  195 + drv->ro = bdrv_is_read_only(drv->bs);
189 } else { 196 } else {
190 drv->disk = FDRIVE_DISK_NONE; 197 drv->disk = FDRIVE_DISK_NONE;
191 drv->last_sect = 1; /* Avoid eventual divide by 0 bugs */ 198 drv->last_sect = 1; /* Avoid eventual divide by 0 bugs */
  199 + drv->ro = 0;
192 } 200 }
193 - drv->ro = ro;  
194 drv->rv = 1; 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 /* Motor control */ 210 /* Motor control */
198 static void fd_start (fdrive_t *drv) 211 static void fd_start (fdrive_t *drv)
199 { 212 {
@@ -220,16 +233,16 @@ static void fdctrl_reset_fifo (void); @@ -220,16 +233,16 @@ static void fdctrl_reset_fifo (void);
220 static int fdctrl_transfer_handler (void *opaque, target_ulong addr, int size); 233 static int fdctrl_transfer_handler (void *opaque, target_ulong addr, int size);
221 static void fdctrl_raise_irq (uint8_t status); 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 enum { 247 enum {
235 FD_CTRL_ACTIVE = 0x01, 248 FD_CTRL_ACTIVE = 0x01,
@@ -295,7 +308,7 @@ typedef struct fdctrl_t { @@ -295,7 +308,7 @@ typedef struct fdctrl_t {
295 static fdctrl_t fdctrl; 308 static fdctrl_t fdctrl;
296 309
297 void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base, 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 // int io_mem; 313 // int io_mem;
301 int i; 314 int i;
@@ -312,8 +325,11 @@ void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base, @@ -312,8 +325,11 @@ void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base,
312 } else { 325 } else {
313 fdctrl.dma_en = 0; 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 fdctrl_reset(0); 333 fdctrl_reset(0);
318 fdctrl.state = FD_CTRL_ACTIVE; 334 fdctrl.state = FD_CTRL_ACTIVE;
319 if (mem_mapped) { 335 if (mem_mapped) {
@@ -323,51 +339,27 @@ void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base, @@ -323,51 +339,27 @@ void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base,
323 cpu_register_physical_memory(base, 0x08, io_mem); 339 cpu_register_physical_memory(base, 0x08, io_mem);
324 #endif 340 #endif
325 } else { 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 /* Change IRQ state */ 365 /* Change IRQ state */
@@ -411,7 +403,7 @@ static void fdctrl_reset (int do_irq) @@ -411,7 +403,7 @@ static void fdctrl_reset (int do_irq)
411 } 403 }
412 404
413 /* Status B register : 0x01 (read-only) */ 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 fdctrl_reset_irq(); 408 fdctrl_reset_irq();
417 FLOPPY_DPRINTF("status register: 0x00\n"); 409 FLOPPY_DPRINTF("status register: 0x00\n");
@@ -420,7 +412,7 @@ static uint32_t fdctrl_read_statusB (CPUState *env, uint32_t reg) @@ -420,7 +412,7 @@ static uint32_t fdctrl_read_statusB (CPUState *env, uint32_t reg)
420 } 412 }
421 413
422 /* Digital output register : 0x02 */ 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 fdrive_t *cur_drv, *drv0, *drv1; 417 fdrive_t *cur_drv, *drv0, *drv1;
426 uint32_t retval = 0; 418 uint32_t retval = 0;
@@ -442,7 +434,7 @@ static uint32_t fdctrl_read_dor (CPUState *env, uint32_t reg) @@ -442,7 +434,7 @@ static uint32_t fdctrl_read_dor (CPUState *env, uint32_t reg)
442 return retval; 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 fdrive_t *drv0, *drv1; 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,7 +481,7 @@ static void fdctrl_write_dor (CPUState *env, uint32_t reg, uint32_t value)
489 } 481 }
490 482
491 /* Tape drive register : 0x03 */ 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 uint32_t retval = 0; 486 uint32_t retval = 0;
495 487
@@ -502,7 +494,7 @@ static uint32_t fdctrl_read_tape (CPUState *env, uint32_t reg) @@ -502,7 +494,7 @@ static uint32_t fdctrl_read_tape (CPUState *env, uint32_t reg)
502 return retval; 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 fdctrl_reset_irq(); 499 fdctrl_reset_irq();
508 /* Reset mode */ 500 /* Reset mode */
@@ -517,7 +509,7 @@ static void fdctrl_write_tape (CPUState *env, uint32_t reg, uint32_t value) @@ -517,7 +509,7 @@ static void fdctrl_write_tape (CPUState *env, uint32_t reg, uint32_t value)
517 } 509 }
518 510
519 /* Main status register : 0x04 (read) */ 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 uint32_t retval = 0; 514 uint32_t retval = 0;
523 515
@@ -541,7 +533,7 @@ static uint32_t fdctrl_read_main_status (CPUState *env, uint32_t reg) @@ -541,7 +533,7 @@ static uint32_t fdctrl_read_main_status (CPUState *env, uint32_t reg)
541 } 533 }
542 534
543 /* Data select rate register : 0x04 (write) */ 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 fdctrl_reset_irq(); 538 fdctrl_reset_irq();
547 /* Reset mode */ 539 /* Reset mode */
@@ -566,7 +558,7 @@ static void fdctrl_write_rate (CPUState *env, uint32_t reg, uint32_t value) @@ -566,7 +558,7 @@ static void fdctrl_write_rate (CPUState *env, uint32_t reg, uint32_t value)
566 } 558 }
567 559
568 /* Digital input register : 0x07 (read-only) */ 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 fdrive_t *drv0, *drv1; 563 fdrive_t *drv0, *drv1;
572 uint32_t retval = 0; 564 uint32_t retval = 0;
@@ -872,7 +864,7 @@ transfer_error: @@ -872,7 +864,7 @@ transfer_error:
872 } 864 }
873 865
874 /* Data register : 0x05 */ 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 fdrive_t *cur_drv, *drv0, *drv1; 869 fdrive_t *cur_drv, *drv0, *drv1;
878 uint32_t retval = 0; 870 uint32_t retval = 0;
@@ -914,7 +906,7 @@ static uint32_t fdctrl_read_data (CPUState *env, uint32_t reg) @@ -914,7 +906,7 @@ static uint32_t fdctrl_read_data (CPUState *env, uint32_t reg)
914 return retval; 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 fdrive_t *cur_drv, *drv0, *drv1; 911 fdrive_t *cur_drv, *drv0, *drv1;
920 912
hw/ide.c
@@ -314,10 +314,10 @@ struct IDEState; @@ -314,10 +314,10 @@ struct IDEState;
314 314
315 typedef void EndTransferFunc(struct IDEState *); 315 typedef void EndTransferFunc(struct IDEState *);
316 316
  317 +/* NOTE: IDEState represents in fact one drive */
317 typedef struct IDEState { 318 typedef struct IDEState {
318 /* ide config */ 319 /* ide config */
319 int is_cdrom; 320 int is_cdrom;
320 - int cdrom_locked;  
321 int cylinders, heads, sectors; 321 int cylinders, heads, sectors;
322 int64_t nb_sectors; 322 int64_t nb_sectors;
323 int mult_sectors; 323 int mult_sectors;
@@ -351,14 +351,6 @@ typedef struct IDEState { @@ -351,14 +351,6 @@ typedef struct IDEState {
351 uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4]; 351 uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
352 } IDEState; 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 static void padstr(char *str, const char *src, int len) 354 static void padstr(char *str, const char *src, int len)
363 { 355 {
364 int i, v; 356 int i, v;
@@ -815,7 +807,7 @@ static void ide_atapi_cmd(IDEState *s) @@ -815,7 +807,7 @@ static void ide_atapi_cmd(IDEState *s)
815 #endif 807 #endif
816 switch(s->io_buffer[0]) { 808 switch(s->io_buffer[0]) {
817 case GPCMD_TEST_UNIT_READY: 809 case GPCMD_TEST_UNIT_READY:
818 - if (s->bs) { 810 + if (bdrv_is_inserted(s->bs)) {
819 ide_atapi_cmd_ok(s); 811 ide_atapi_cmd_ok(s);
820 } else { 812 } else {
821 ide_atapi_cmd_error(s, SENSE_NOT_READY, 813 ide_atapi_cmd_error(s, SENSE_NOT_READY,
@@ -867,7 +859,7 @@ static void ide_atapi_cmd(IDEState *s) @@ -867,7 +859,7 @@ static void ide_atapi_cmd(IDEState *s)
867 buf[12] = 0x70; 859 buf[12] = 0x70;
868 buf[13] = 3 << 5; 860 buf[13] = 3 << 5;
869 buf[14] = (1 << 0) | (1 << 3) | (1 << 5); 861 buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
870 - if (s->cdrom_locked) 862 + if (bdrv_is_locked(s->bs))
871 buf[6] |= 1 << 1; 863 buf[6] |= 1 << 1;
872 buf[15] = 0x00; 864 buf[15] = 0x00;
873 cpu_to_ube16(&buf[16], 706); 865 cpu_to_ube16(&buf[16], 706);
@@ -907,8 +899,8 @@ static void ide_atapi_cmd(IDEState *s) @@ -907,8 +899,8 @@ static void ide_atapi_cmd(IDEState *s)
907 ide_atapi_cmd_reply(s, 18, max_len); 899 ide_atapi_cmd_reply(s, 18, max_len);
908 break; 900 break;
909 case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL: 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 ide_atapi_cmd_ok(s); 904 ide_atapi_cmd_ok(s);
913 } else { 905 } else {
914 ide_atapi_cmd_error(s, SENSE_NOT_READY, 906 ide_atapi_cmd_error(s, SENSE_NOT_READY,
@@ -920,7 +912,7 @@ static void ide_atapi_cmd(IDEState *s) @@ -920,7 +912,7 @@ static void ide_atapi_cmd(IDEState *s)
920 { 912 {
921 int nb_sectors, lba; 913 int nb_sectors, lba;
922 914
923 - if (!s->bs) { 915 + if (!bdrv_is_inserted(s->bs)) {
924 ide_atapi_cmd_error(s, SENSE_NOT_READY, 916 ide_atapi_cmd_error(s, SENSE_NOT_READY,
925 ASC_MEDIUM_NOT_PRESENT); 917 ASC_MEDIUM_NOT_PRESENT);
926 break; 918 break;
@@ -945,7 +937,7 @@ static void ide_atapi_cmd(IDEState *s) @@ -945,7 +937,7 @@ static void ide_atapi_cmd(IDEState *s)
945 case GPCMD_SEEK: 937 case GPCMD_SEEK:
946 { 938 {
947 int lba; 939 int lba;
948 - if (!s->bs) { 940 + if (!bdrv_is_inserted(s->bs)) {
949 ide_atapi_cmd_error(s, SENSE_NOT_READY, 941 ide_atapi_cmd_error(s, SENSE_NOT_READY,
950 ASC_MEDIUM_NOT_PRESENT); 942 ASC_MEDIUM_NOT_PRESENT);
951 break; 943 break;
@@ -965,7 +957,10 @@ static void ide_atapi_cmd(IDEState *s) @@ -965,7 +957,10 @@ static void ide_atapi_cmd(IDEState *s)
965 start = packet[4] & 1; 957 start = packet[4] & 1;
966 eject = (packet[4] >> 1) & 1; 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 ide_atapi_cmd_ok(s); 964 ide_atapi_cmd_ok(s);
970 } 965 }
971 break; 966 break;
@@ -986,7 +981,7 @@ static void ide_atapi_cmd(IDEState *s) @@ -986,7 +981,7 @@ static void ide_atapi_cmd(IDEState *s)
986 { 981 {
987 int format, msf, start_track, len; 982 int format, msf, start_track, len;
988 983
989 - if (!s->bs) { 984 + if (!bdrv_is_inserted(s->bs)) {
990 ide_atapi_cmd_error(s, SENSE_NOT_READY, 985 ide_atapi_cmd_error(s, SENSE_NOT_READY,
991 ASC_MEDIUM_NOT_PRESENT); 986 ASC_MEDIUM_NOT_PRESENT);
992 break; 987 break;
@@ -1019,7 +1014,7 @@ static void ide_atapi_cmd(IDEState *s) @@ -1019,7 +1014,7 @@ static void ide_atapi_cmd(IDEState *s)
1019 } 1014 }
1020 break; 1015 break;
1021 case GPCMD_READ_CDVD_CAPACITY: 1016 case GPCMD_READ_CDVD_CAPACITY:
1022 - if (!s->bs) { 1017 + if (!bdrv_is_inserted(s->bs)) {
1023 ide_atapi_cmd_error(s, SENSE_NOT_READY, 1018 ide_atapi_cmd_error(s, SENSE_NOT_READY,
1024 ASC_MEDIUM_NOT_PRESENT); 1019 ASC_MEDIUM_NOT_PRESENT);
1025 break; 1020 break;
@@ -1051,9 +1046,20 @@ static void ide_atapi_cmd(IDEState *s) @@ -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 IDEState *s = ide_if->cur_drive; 1063 IDEState *s = ide_if->cur_drive;
1058 int unit, n; 1064 int unit, n;
1059 1065
@@ -1210,9 +1216,9 @@ static void ide_ioport_write(CPUState *env, uint32_t addr, uint32_t val) @@ -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 uint32_t addr; 1222 uint32_t addr;
1217 int ret; 1223 int ret;
1218 1224
@@ -1251,9 +1257,9 @@ static uint32_t ide_ioport_read(CPUState *env, uint32_t addr1) @@ -1251,9 +1257,9 @@ static uint32_t ide_ioport_read(CPUState *env, uint32_t addr1)
1251 return ret; 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 int ret; 1263 int ret;
1258 ret = s->status; 1264 ret = s->status;
1259 #ifdef DEBUG_IDE 1265 #ifdef DEBUG_IDE
@@ -1262,9 +1268,9 @@ static uint32_t ide_status_read(CPUState *env, uint32_t addr) @@ -1262,9 +1268,9 @@ static uint32_t ide_status_read(CPUState *env, uint32_t addr)
1262 return ret; 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 IDEState *s; 1274 IDEState *s;
1269 int i; 1275 int i;
1270 1276
@@ -1297,9 +1303,9 @@ static void ide_cmd_write(CPUState *env, uint32_t addr, uint32_t val) @@ -1297,9 +1303,9 @@ static void ide_cmd_write(CPUState *env, uint32_t addr, uint32_t val)
1297 ide_if[1].cmd = val; 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 uint8_t *p; 1309 uint8_t *p;
1304 1310
1305 p = s->data_ptr; 1311 p = s->data_ptr;
@@ -1310,9 +1316,9 @@ static void ide_data_writew(CPUState *env, uint32_t addr, uint32_t val) @@ -1310,9 +1316,9 @@ static void ide_data_writew(CPUState *env, uint32_t addr, uint32_t val)
1310 s->end_transfer_func(s); 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 uint8_t *p; 1322 uint8_t *p;
1317 int ret; 1323 int ret;
1318 p = s->data_ptr; 1324 p = s->data_ptr;
@@ -1324,9 +1330,9 @@ static uint32_t ide_data_readw(CPUState *env, uint32_t addr) @@ -1324,9 +1330,9 @@ static uint32_t ide_data_readw(CPUState *env, uint32_t addr)
1324 return ret; 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 uint8_t *p; 1336 uint8_t *p;
1331 1337
1332 p = s->data_ptr; 1338 p = s->data_ptr;
@@ -1337,9 +1343,9 @@ static void ide_data_writel(CPUState *env, uint32_t addr, uint32_t val) @@ -1337,9 +1343,9 @@ static void ide_data_writel(CPUState *env, uint32_t addr, uint32_t val)
1337 s->end_transfer_func(s); 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 uint8_t *p; 1349 uint8_t *p;
1344 int ret; 1350 int ret;
1345 1351
@@ -1407,64 +1413,64 @@ static void ide_guess_geometry(IDEState *s) @@ -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 int64_t nb_sectors; 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 if (s->bs) { 1433 if (s->bs) {
1423 bdrv_get_geometry(s->bs, &nb_sectors); 1434 bdrv_get_geometry(s->bs, &nb_sectors);
1424 s->nb_sectors = nb_sectors; 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 s->cylinders = cylinders; 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 ide_reset(s); 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 }