removable device support - io port API change

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@659 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2004-03-14 21:40:43 +00:00
parent b338082b3f
commit caed880216
2 changed files with 151 additions and 153 deletions

134
hw/fdc.c
View File

@ -85,12 +85,14 @@ typedef struct fdrive_t {
uint8_t ro; /* Is read-only */ uint8_t ro; /* Is read-only */
} fdrive_t; } fdrive_t;
static void fd_init (fdrive_t *drv) static void fd_init (fdrive_t *drv, BlockDriverState *bs)
{ {
/* Drive */ /* Drive */
drv->bs = NULL; drv->bs = bs;
// drv->drive = FDRIVE_DRV_288; if (bs)
drv->drive = FDRIVE_DRV_144; drv->drive = FDRIVE_DRV_144;
else
drv->drive = FDRIVE_DRV_NONE;
drv->motor = 0; drv->motor = 0;
drv->perpendicular = 0; drv->perpendicular = 0;
drv->rv = 0; drv->rv = 0;
@ -157,13 +159,17 @@ static void fd_recalibrate (fdrive_t *drv)
} }
/* Revalidate a disk drive after a disk change */ /* Revalidate a disk drive after a disk change */
static void fd_revalidate (fdrive_t *drv, int ro) static void fd_revalidate (fdrive_t *drv)
{ {
int64_t nb_sectors; int64_t nb_sectors;
FLOPPY_DPRINTF("revalidate\n"); FLOPPY_DPRINTF("revalidate\n");
drv->rv = 0; drv->rv = 0;
if (drv->bs != NULL) { /* if no drive present, cannot do more */
if (!drv->bs)
return;
if (bdrv_is_inserted(drv->bs)) {
bdrv_get_geometry(drv->bs, &nb_sectors); bdrv_get_geometry(drv->bs, &nb_sectors);
#if 1 #if 1
if (nb_sectors > 2880) if (nb_sectors > 2880)
@ -186,14 +192,21 @@ static void fd_revalidate (fdrive_t *drv, int ro)
drv->max_track = 80; drv->max_track = 80;
#endif #endif
} }
drv->ro = bdrv_is_read_only(drv->bs);
} else { } else {
drv->disk = FDRIVE_DISK_NONE; drv->disk = FDRIVE_DISK_NONE;
drv->last_sect = 1; /* Avoid eventual divide by 0 bugs */ drv->last_sect = 1; /* Avoid eventual divide by 0 bugs */
drv->ro = 0;
} }
drv->ro = ro;
drv->rv = 1; drv->rv = 1;
} }
static void fd_change_cb (void *opaque)
{
fdrive_t *drv = opaque;
fd_revalidate(drv);
}
/* Motor control */ /* Motor control */
static void fd_start (fdrive_t *drv) static void fd_start (fdrive_t *drv)
{ {
@ -220,16 +233,16 @@ static void fdctrl_reset_fifo (void);
static int fdctrl_transfer_handler (void *opaque, target_ulong addr, int size); static int fdctrl_transfer_handler (void *opaque, target_ulong addr, int size);
static void fdctrl_raise_irq (uint8_t status); static void fdctrl_raise_irq (uint8_t status);
static uint32_t fdctrl_read_statusB (CPUState *env, uint32_t reg); static uint32_t fdctrl_read_statusB (void *opaque, uint32_t reg);
static uint32_t fdctrl_read_dor (CPUState *env, uint32_t reg); static uint32_t fdctrl_read_dor (void *opaque, uint32_t reg);
static void fdctrl_write_dor (CPUState *env, uint32_t reg, uint32_t value); static void fdctrl_write_dor (void *opaque, uint32_t reg, uint32_t value);
static uint32_t fdctrl_read_tape (CPUState *env, uint32_t reg); static uint32_t fdctrl_read_tape (void *opaque, uint32_t reg);
static void fdctrl_write_tape (CPUState *env, uint32_t reg, uint32_t value); static void fdctrl_write_tape (void *opaque, uint32_t reg, uint32_t value);
static uint32_t fdctrl_read_main_status (CPUState *env, uint32_t reg); static uint32_t fdctrl_read_main_status (void *opaque, uint32_t reg);
static void fdctrl_write_rate (CPUState *env, uint32_t reg, uint32_t value); static void fdctrl_write_rate (void *opaque, uint32_t reg, uint32_t value);
static uint32_t fdctrl_read_data (CPUState *env, uint32_t reg); static uint32_t fdctrl_read_data (void *opaque, uint32_t reg);
static void fdctrl_write_data (CPUState *env, uint32_t reg, uint32_t value); static void fdctrl_write_data (void *opaque, uint32_t reg, uint32_t value);
static uint32_t fdctrl_read_dir (CPUState *env, uint32_t reg); static uint32_t fdctrl_read_dir (void *opaque, uint32_t reg);
enum { enum {
FD_CTRL_ACTIVE = 0x01, FD_CTRL_ACTIVE = 0x01,
@ -295,7 +308,7 @@ typedef struct fdctrl_t {
static fdctrl_t fdctrl; static fdctrl_t fdctrl;
void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base, void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base,
char boot_device) BlockDriverState **fds)
{ {
// int io_mem; // int io_mem;
int i; int i;
@ -312,8 +325,11 @@ void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base,
} else { } else {
fdctrl.dma_en = 0; fdctrl.dma_en = 0;
} }
for (i = 0; i < MAX_FD; i++) for (i = 0; i < MAX_FD; i++) {
fd_init(&fdctrl.drives[i]); fd_init(&fdctrl.drives[i], fds[i]);
if (fds[i])
bdrv_set_change_cb(fds[i], fd_change_cb, &fdctrl.drives[i]);
}
fdctrl_reset(0); fdctrl_reset(0);
fdctrl.state = FD_CTRL_ACTIVE; fdctrl.state = FD_CTRL_ACTIVE;
if (mem_mapped) { if (mem_mapped) {
@ -323,51 +339,27 @@ void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base,
cpu_register_physical_memory(base, 0x08, io_mem); cpu_register_physical_memory(base, 0x08, io_mem);
#endif #endif
} else { } else {
register_ioport_read(base + 0x01, 1, fdctrl_read_statusB, 1); register_ioport_read(base + 0x01, 1, 1, fdctrl_read_statusB, NULL);
register_ioport_read(base + 0x02, 1, fdctrl_read_dor, 1); register_ioport_read(base + 0x02, 1, 1, fdctrl_read_dor, NULL);
register_ioport_write(base + 0x02, 1, fdctrl_write_dor, 1); register_ioport_write(base + 0x02, 1, 1, fdctrl_write_dor, NULL);
register_ioport_read(base + 0x03, 1, fdctrl_read_tape, 1); register_ioport_read(base + 0x03, 1, 1, fdctrl_read_tape, NULL);
register_ioport_write(base + 0x03, 1, fdctrl_write_tape, 1); register_ioport_write(base + 0x03, 1, 1, fdctrl_write_tape, NULL);
register_ioport_read(base + 0x04, 1, fdctrl_read_main_status, 1); register_ioport_read(base + 0x04, 1, 1, fdctrl_read_main_status, NULL);
register_ioport_write(base + 0x04, 1, fdctrl_write_rate, 1); register_ioport_write(base + 0x04, 1, 1, fdctrl_write_rate, NULL);
register_ioport_read(base + 0x05, 1, fdctrl_read_data, 1); register_ioport_read(base + 0x05, 1, 1, fdctrl_read_data, NULL);
register_ioport_write(base + 0x05, 1, fdctrl_write_data, 1); register_ioport_write(base + 0x05, 1, 1, fdctrl_write_data, NULL);
register_ioport_read(base + 0x07, 1, fdctrl_read_dir, 1); register_ioport_read(base + 0x07, 1, 1, fdctrl_read_dir, NULL);
}
fdctrl.bootsel = 0;
for (i = 0; i < MAX_FD; i++) {
fd_revalidate(&fdctrl.drives[i]);
} }
if (boot_device == 'b')
fdctrl.bootsel = 1;
else
fdctrl.bootsel = 0;
#if defined (TARGET_I386)
cmos_register_fd(fdctrl.drives[0].drive, fdctrl.drives[1].drive);
#endif
} }
int fdctrl_disk_change (int idx, const unsigned char *filename, int ro) int fdctrl_get_drive_type(int drive_num)
{ {
fdrive_t *drv; return fdctrl.drives[drive_num].drive;
if (idx < 0 || idx > 1)
return -1;
FLOPPY_DPRINTF("disk %d change: %s (%s)\n", idx, filename,
ro == 0 ? "rw" : "ro");
drv = &fdctrl.drives[idx];
if (fd_table[idx] != NULL) {
bdrv_close(fd_table[idx]);
fd_table[idx] = NULL;
}
fd_table[idx] = bdrv_open(filename, ro);
drv->bs = fd_table[idx];
if (fd_table[idx] == NULL)
return -1;
fd_revalidate(drv, ro);
#if 0
fd_recalibrate(drv);
fdctrl_reset_fifo();
fdctrl_raise_irq(0x20);
#endif
return 0;
} }
/* Change IRQ state */ /* Change IRQ state */
@ -411,7 +403,7 @@ static void fdctrl_reset (int do_irq)
} }
/* Status B register : 0x01 (read-only) */ /* Status B register : 0x01 (read-only) */
static uint32_t fdctrl_read_statusB (CPUState *env, uint32_t reg) static uint32_t fdctrl_read_statusB (void *opaque, uint32_t reg)
{ {
fdctrl_reset_irq(); fdctrl_reset_irq();
FLOPPY_DPRINTF("status register: 0x00\n"); FLOPPY_DPRINTF("status register: 0x00\n");
@ -420,7 +412,7 @@ static uint32_t fdctrl_read_statusB (CPUState *env, uint32_t reg)
} }
/* Digital output register : 0x02 */ /* Digital output register : 0x02 */
static uint32_t fdctrl_read_dor (CPUState *env, uint32_t reg) static uint32_t fdctrl_read_dor (void *opaque, uint32_t reg)
{ {
fdrive_t *cur_drv, *drv0, *drv1; fdrive_t *cur_drv, *drv0, *drv1;
uint32_t retval = 0; uint32_t retval = 0;
@ -442,7 +434,7 @@ static uint32_t fdctrl_read_dor (CPUState *env, uint32_t reg)
return retval; return retval;
} }
static void fdctrl_write_dor (CPUState *env, uint32_t reg, uint32_t value) static void fdctrl_write_dor (void *opaque, uint32_t reg, uint32_t value)
{ {
fdrive_t *drv0, *drv1; fdrive_t *drv0, *drv1;
@ -489,7 +481,7 @@ static void fdctrl_write_dor (CPUState *env, uint32_t reg, uint32_t value)
} }
/* Tape drive register : 0x03 */ /* Tape drive register : 0x03 */
static uint32_t fdctrl_read_tape (CPUState *env, uint32_t reg) static uint32_t fdctrl_read_tape (void *opaque, uint32_t reg)
{ {
uint32_t retval = 0; uint32_t retval = 0;
@ -502,7 +494,7 @@ static uint32_t fdctrl_read_tape (CPUState *env, uint32_t reg)
return retval; return retval;
} }
static void fdctrl_write_tape (CPUState *env, uint32_t reg, uint32_t value) static void fdctrl_write_tape (void *opaque, uint32_t reg, uint32_t value)
{ {
fdctrl_reset_irq(); fdctrl_reset_irq();
/* Reset mode */ /* Reset mode */
@ -517,7 +509,7 @@ static void fdctrl_write_tape (CPUState *env, uint32_t reg, uint32_t value)
} }
/* Main status register : 0x04 (read) */ /* Main status register : 0x04 (read) */
static uint32_t fdctrl_read_main_status (CPUState *env, uint32_t reg) static uint32_t fdctrl_read_main_status (void *opaque, uint32_t reg)
{ {
uint32_t retval = 0; uint32_t retval = 0;
@ -541,7 +533,7 @@ static uint32_t fdctrl_read_main_status (CPUState *env, uint32_t reg)
} }
/* Data select rate register : 0x04 (write) */ /* Data select rate register : 0x04 (write) */
static void fdctrl_write_rate (CPUState *env, uint32_t reg, uint32_t value) static void fdctrl_write_rate (void *opaque, uint32_t reg, uint32_t value)
{ {
fdctrl_reset_irq(); fdctrl_reset_irq();
/* Reset mode */ /* Reset mode */
@ -566,7 +558,7 @@ static void fdctrl_write_rate (CPUState *env, uint32_t reg, uint32_t value)
} }
/* Digital input register : 0x07 (read-only) */ /* Digital input register : 0x07 (read-only) */
static uint32_t fdctrl_read_dir (CPUState *env, uint32_t reg) static uint32_t fdctrl_read_dir (void *opaque, uint32_t reg)
{ {
fdrive_t *drv0, *drv1; fdrive_t *drv0, *drv1;
uint32_t retval = 0; uint32_t retval = 0;
@ -872,7 +864,7 @@ transfer_error:
} }
/* Data register : 0x05 */ /* Data register : 0x05 */
static uint32_t fdctrl_read_data (CPUState *env, uint32_t reg) static uint32_t fdctrl_read_data (void *opaque, uint32_t reg)
{ {
fdrive_t *cur_drv, *drv0, *drv1; fdrive_t *cur_drv, *drv0, *drv1;
uint32_t retval = 0; uint32_t retval = 0;
@ -914,7 +906,7 @@ static uint32_t fdctrl_read_data (CPUState *env, uint32_t reg)
return retval; return retval;
} }
static void fdctrl_write_data (CPUState *env, uint32_t reg, uint32_t value) static void fdctrl_write_data (void *opaque, uint32_t reg, uint32_t value)
{ {
fdrive_t *cur_drv, *drv0, *drv1; fdrive_t *cur_drv, *drv0, *drv1;

170
hw/ide.c
View File

@ -314,10 +314,10 @@ struct IDEState;
typedef void EndTransferFunc(struct IDEState *); typedef void EndTransferFunc(struct IDEState *);
/* NOTE: IDEState represents in fact one drive */
typedef struct IDEState { typedef struct IDEState {
/* ide config */ /* ide config */
int is_cdrom; int is_cdrom;
int cdrom_locked;
int cylinders, heads, sectors; int cylinders, heads, sectors;
int64_t nb_sectors; int64_t nb_sectors;
int mult_sectors; int mult_sectors;
@ -351,14 +351,6 @@ typedef struct IDEState {
uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4]; uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
} IDEState; } IDEState;
IDEState ide_state[MAX_DISKS];
IDEState *ide_table[0x400 >> 3];
static inline IDEState *get_ide_interface(uint32_t addr)
{
return ide_table[addr >> 3];
}
static void padstr(char *str, const char *src, int len) static void padstr(char *str, const char *src, int len)
{ {
int i, v; int i, v;
@ -815,7 +807,7 @@ static void ide_atapi_cmd(IDEState *s)
#endif #endif
switch(s->io_buffer[0]) { switch(s->io_buffer[0]) {
case GPCMD_TEST_UNIT_READY: case GPCMD_TEST_UNIT_READY:
if (s->bs) { if (bdrv_is_inserted(s->bs)) {
ide_atapi_cmd_ok(s); ide_atapi_cmd_ok(s);
} else { } else {
ide_atapi_cmd_error(s, SENSE_NOT_READY, ide_atapi_cmd_error(s, SENSE_NOT_READY,
@ -867,7 +859,7 @@ static void ide_atapi_cmd(IDEState *s)
buf[12] = 0x70; buf[12] = 0x70;
buf[13] = 3 << 5; buf[13] = 3 << 5;
buf[14] = (1 << 0) | (1 << 3) | (1 << 5); buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
if (s->cdrom_locked) if (bdrv_is_locked(s->bs))
buf[6] |= 1 << 1; buf[6] |= 1 << 1;
buf[15] = 0x00; buf[15] = 0x00;
cpu_to_ube16(&buf[16], 706); cpu_to_ube16(&buf[16], 706);
@ -907,8 +899,8 @@ static void ide_atapi_cmd(IDEState *s)
ide_atapi_cmd_reply(s, 18, max_len); ide_atapi_cmd_reply(s, 18, max_len);
break; break;
case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL: case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
if (s->bs) { if (bdrv_is_inserted(s->bs)) {
s->cdrom_locked = packet[4] & 1; bdrv_set_locked(s->bs, packet[4] & 1);
ide_atapi_cmd_ok(s); ide_atapi_cmd_ok(s);
} else { } else {
ide_atapi_cmd_error(s, SENSE_NOT_READY, ide_atapi_cmd_error(s, SENSE_NOT_READY,
@ -920,7 +912,7 @@ static void ide_atapi_cmd(IDEState *s)
{ {
int nb_sectors, lba; int nb_sectors, lba;
if (!s->bs) { if (!bdrv_is_inserted(s->bs)) {
ide_atapi_cmd_error(s, SENSE_NOT_READY, ide_atapi_cmd_error(s, SENSE_NOT_READY,
ASC_MEDIUM_NOT_PRESENT); ASC_MEDIUM_NOT_PRESENT);
break; break;
@ -945,7 +937,7 @@ static void ide_atapi_cmd(IDEState *s)
case GPCMD_SEEK: case GPCMD_SEEK:
{ {
int lba; int lba;
if (!s->bs) { if (!bdrv_is_inserted(s->bs)) {
ide_atapi_cmd_error(s, SENSE_NOT_READY, ide_atapi_cmd_error(s, SENSE_NOT_READY,
ASC_MEDIUM_NOT_PRESENT); ASC_MEDIUM_NOT_PRESENT);
break; break;
@ -965,7 +957,10 @@ static void ide_atapi_cmd(IDEState *s)
start = packet[4] & 1; start = packet[4] & 1;
eject = (packet[4] >> 1) & 1; eject = (packet[4] >> 1) & 1;
/* XXX: currently none implemented */ if (eject && !start) {
/* eject the disk */
bdrv_close(s->bs);
}
ide_atapi_cmd_ok(s); ide_atapi_cmd_ok(s);
} }
break; break;
@ -986,7 +981,7 @@ static void ide_atapi_cmd(IDEState *s)
{ {
int format, msf, start_track, len; int format, msf, start_track, len;
if (!s->bs) { if (!bdrv_is_inserted(s->bs)) {
ide_atapi_cmd_error(s, SENSE_NOT_READY, ide_atapi_cmd_error(s, SENSE_NOT_READY,
ASC_MEDIUM_NOT_PRESENT); ASC_MEDIUM_NOT_PRESENT);
break; break;
@ -1019,7 +1014,7 @@ static void ide_atapi_cmd(IDEState *s)
} }
break; break;
case GPCMD_READ_CDVD_CAPACITY: case GPCMD_READ_CDVD_CAPACITY:
if (!s->bs) { if (!bdrv_is_inserted(s->bs)) {
ide_atapi_cmd_error(s, SENSE_NOT_READY, ide_atapi_cmd_error(s, SENSE_NOT_READY,
ASC_MEDIUM_NOT_PRESENT); ASC_MEDIUM_NOT_PRESENT);
break; break;
@ -1051,9 +1046,20 @@ static void ide_atapi_cmd(IDEState *s)
} }
} }
static void ide_ioport_write(CPUState *env, uint32_t addr, uint32_t val) /* called when the inserted state of the media has changed */
static void cdrom_change_cb(void *opaque)
{ {
IDEState *ide_if = get_ide_interface(addr); IDEState *s = opaque;
int64_t nb_sectors;
/* XXX: send interrupt too */
bdrv_get_geometry(s->bs, &nb_sectors);
s->nb_sectors = nb_sectors;
}
static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
{
IDEState *ide_if = opaque;
IDEState *s = ide_if->cur_drive; IDEState *s = ide_if->cur_drive;
int unit, n; int unit, n;
@ -1210,9 +1216,9 @@ static void ide_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
} }
} }
static uint32_t ide_ioport_read(CPUState *env, uint32_t addr1) static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
{ {
IDEState *s = get_ide_interface(addr1)->cur_drive; IDEState *s = ((IDEState *)opaque)->cur_drive;
uint32_t addr; uint32_t addr;
int ret; int ret;
@ -1251,9 +1257,9 @@ static uint32_t ide_ioport_read(CPUState *env, uint32_t addr1)
return ret; return ret;
} }
static uint32_t ide_status_read(CPUState *env, uint32_t addr) static uint32_t ide_status_read(void *opaque, uint32_t addr)
{ {
IDEState *s = get_ide_interface(addr)->cur_drive; IDEState *s = ((IDEState *)opaque)->cur_drive;
int ret; int ret;
ret = s->status; ret = s->status;
#ifdef DEBUG_IDE #ifdef DEBUG_IDE
@ -1262,9 +1268,9 @@ static uint32_t ide_status_read(CPUState *env, uint32_t addr)
return ret; return ret;
} }
static void ide_cmd_write(CPUState *env, uint32_t addr, uint32_t val) static void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
{ {
IDEState *ide_if = get_ide_interface(addr); IDEState *ide_if = opaque;
IDEState *s; IDEState *s;
int i; int i;
@ -1297,9 +1303,9 @@ static void ide_cmd_write(CPUState *env, uint32_t addr, uint32_t val)
ide_if[1].cmd = val; ide_if[1].cmd = val;
} }
static void ide_data_writew(CPUState *env, uint32_t addr, uint32_t val) static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
{ {
IDEState *s = get_ide_interface(addr)->cur_drive; IDEState *s = ((IDEState *)opaque)->cur_drive;
uint8_t *p; uint8_t *p;
p = s->data_ptr; p = s->data_ptr;
@ -1310,9 +1316,9 @@ static void ide_data_writew(CPUState *env, uint32_t addr, uint32_t val)
s->end_transfer_func(s); s->end_transfer_func(s);
} }
static uint32_t ide_data_readw(CPUState *env, uint32_t addr) static uint32_t ide_data_readw(void *opaque, uint32_t addr)
{ {
IDEState *s = get_ide_interface(addr)->cur_drive; IDEState *s = ((IDEState *)opaque)->cur_drive;
uint8_t *p; uint8_t *p;
int ret; int ret;
p = s->data_ptr; p = s->data_ptr;
@ -1324,9 +1330,9 @@ static uint32_t ide_data_readw(CPUState *env, uint32_t addr)
return ret; return ret;
} }
static void ide_data_writel(CPUState *env, uint32_t addr, uint32_t val) static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
{ {
IDEState *s = get_ide_interface(addr)->cur_drive; IDEState *s = ((IDEState *)opaque)->cur_drive;
uint8_t *p; uint8_t *p;
p = s->data_ptr; p = s->data_ptr;
@ -1337,9 +1343,9 @@ static void ide_data_writel(CPUState *env, uint32_t addr, uint32_t val)
s->end_transfer_func(s); s->end_transfer_func(s);
} }
static uint32_t ide_data_readl(CPUState *env, uint32_t addr) static uint32_t ide_data_readl(void *opaque, uint32_t addr)
{ {
IDEState *s = get_ide_interface(addr)->cur_drive; IDEState *s = ((IDEState *)opaque)->cur_drive;
uint8_t *p; uint8_t *p;
int ret; int ret;
@ -1407,64 +1413,64 @@ static void ide_guess_geometry(IDEState *s)
} }
} }
void ide_init(void) void ide_init(int iobase, int iobase2, int irq,
BlockDriverState *hd0, BlockDriverState *hd1)
{ {
IDEState *s; IDEState *s, *ide_state;
int i, cylinders, iobase, iobase2; int i, cylinders, heads, secs;
int64_t nb_sectors; int64_t nb_sectors;
static const int ide_iobase[2] = { 0x1f0, 0x170 };
static const int ide_iobase2[2] = { 0x3f6, 0x376 };
static const int ide_irq[2] = { 14, 15 };
for(i = 0; i < MAX_DISKS; i++) { ide_state = qemu_mallocz(sizeof(IDEState) * 2);
s = &ide_state[i]; if (!ide_state)
s->bs = bs_table[i]; return;
for(i = 0; i < 2; i++) {
s = ide_state + i;
if (i == 0)
s->bs = hd0;
else
s->bs = hd1;
if (s->bs) { if (s->bs) {
bdrv_get_geometry(s->bs, &nb_sectors); bdrv_get_geometry(s->bs, &nb_sectors);
s->nb_sectors = nb_sectors; s->nb_sectors = nb_sectors;
ide_guess_geometry(s); /* if a geometry hint is available, use it */
if (s->cylinders == 0) { bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
/* if no geometry, use a LBA compatible one */ if (cylinders != 0) {
cylinders = nb_sectors / (16 * 63);
if (cylinders > 16383)
cylinders = 16383;
else if (cylinders < 2)
cylinders = 2;
s->cylinders = cylinders; s->cylinders = cylinders;
s->heads = 16; s->heads = heads;
s->sectors = 63; s->sectors = secs;
} else {
ide_guess_geometry(s);
if (s->cylinders == 0) {
/* if no geometry, use a LBA compatible one */
cylinders = nb_sectors / (16 * 63);
if (cylinders > 16383)
cylinders = 16383;
else if (cylinders < 2)
cylinders = 2;
s->cylinders = cylinders;
s->heads = 16;
s->sectors = 63;
}
}
if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
s->is_cdrom = 1;
bdrv_set_change_cb(s->bs, cdrom_change_cb, s);
} }
} }
s->irq = ide_irq[i >> 1]; s->irq = irq;
ide_reset(s); ide_reset(s);
} }
for(i = 0; i < (MAX_DISKS / 2); i++) { register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state);
iobase = ide_iobase[i]; register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state);
iobase2 = ide_iobase2[i]; if (iobase2) {
ide_table[iobase >> 3] = &ide_state[2 * i]; register_ioport_read(iobase2, 1, 1, ide_status_read, ide_state);
if (ide_iobase2[i]) register_ioport_write(iobase2, 1, 1, ide_cmd_write, ide_state);
ide_table[iobase2 >> 3] = &ide_state[2 * i];
register_ioport_write(iobase, 8, ide_ioport_write, 1);
register_ioport_read(iobase, 8, ide_ioport_read, 1);
register_ioport_read(iobase2, 1, ide_status_read, 1);
register_ioport_write(iobase2, 1, ide_cmd_write, 1);
/* data ports */
register_ioport_write(iobase, 2, ide_data_writew, 2);
register_ioport_read(iobase, 2, ide_data_readw, 2);
register_ioport_write(iobase, 4, ide_data_writel, 4);
register_ioport_read(iobase, 4, ide_data_readl, 4);
} }
}
/* data ports */
void ide_set_geometry(int n, int cyls, int heads, int secs) register_ioport_write(iobase, 2, 2, ide_data_writew, ide_state);
{ register_ioport_read(iobase, 2, 2, ide_data_readw, ide_state);
ide_state[n].cylinders = cyls; register_ioport_write(iobase, 4, 4, ide_data_writel, ide_state);
ide_state[n].heads = heads; register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state);
ide_state[n].sectors = secs;
}
void ide_set_cdrom(int n, int is_cdrom)
{
ide_state[n].is_cdrom = is_cdrom;
} }