fdc: Reject unimplemented error actions
drive_init() doesn't permit them for if=floppy, but that's worthless: we get them via if=none and -global. This can make device initialization fail. Since all callers of fdctrl_init_isa() ignore its value, change it to die instead of returning failure. Without this, some callers would ignore the failure, and others would crash. Wart: unlike drive_init(), we don't reject the default action when it's explicitly specified. That's because we can't distinguish "no rerror option" from "rerror=report", or "no werror" from "rerror=enospc". Left for another day. Signed-off-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
		
							parent
							
								
									65d21bc73b
								
							
						
					
					
						commit
						b47b35250f
					
				
							
								
								
									
										22
									
								
								hw/fdc.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								hw/fdc.c
									
									
									
									
									
								
							@ -29,6 +29,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "hw.h"
 | 
					#include "hw.h"
 | 
				
			||||||
#include "fdc.h"
 | 
					#include "fdc.h"
 | 
				
			||||||
 | 
					#include "qemu-error.h"
 | 
				
			||||||
#include "qemu-timer.h"
 | 
					#include "qemu-timer.h"
 | 
				
			||||||
#include "isa.h"
 | 
					#include "isa.h"
 | 
				
			||||||
#include "sysbus.h"
 | 
					#include "sysbus.h"
 | 
				
			||||||
@ -1844,7 +1845,7 @@ static void fdctrl_result_timer(void *opaque)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Init functions */
 | 
					/* Init functions */
 | 
				
			||||||
static void fdctrl_connect_drives(FDCtrl *fdctrl)
 | 
					static int fdctrl_connect_drives(FDCtrl *fdctrl)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    unsigned int i;
 | 
					    unsigned int i;
 | 
				
			||||||
    FDrive *drive;
 | 
					    FDrive *drive;
 | 
				
			||||||
@ -1852,12 +1853,24 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl)
 | 
				
			|||||||
    for (i = 0; i < MAX_FD; i++) {
 | 
					    for (i = 0; i < MAX_FD; i++) {
 | 
				
			||||||
        drive = &fdctrl->drives[i];
 | 
					        drive = &fdctrl->drives[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (drive->bs) {
 | 
				
			||||||
 | 
					            if (bdrv_get_on_error(drive->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
 | 
				
			||||||
 | 
					                error_report("fdc doesn't support drive option werror");
 | 
				
			||||||
 | 
					                return -1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (bdrv_get_on_error(drive->bs, 1) != BLOCK_ERR_REPORT) {
 | 
				
			||||||
 | 
					                error_report("fdc doesn't support drive option rerror");
 | 
				
			||||||
 | 
					                return -1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        fd_init(drive);
 | 
					        fd_init(drive);
 | 
				
			||||||
        fd_revalidate(drive);
 | 
					        fd_revalidate(drive);
 | 
				
			||||||
        if (drive->bs) {
 | 
					        if (drive->bs) {
 | 
				
			||||||
            bdrv_set_removable(drive->bs, 1);
 | 
					            bdrv_set_removable(drive->bs, 1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FDCtrl *fdctrl_init_isa(DriveInfo **fds)
 | 
					FDCtrl *fdctrl_init_isa(DriveInfo **fds)
 | 
				
			||||||
@ -1871,8 +1884,7 @@ FDCtrl *fdctrl_init_isa(DriveInfo **fds)
 | 
				
			|||||||
    if (fds[1]) {
 | 
					    if (fds[1]) {
 | 
				
			||||||
        qdev_prop_set_drive_nofail(&dev->qdev, "driveB", fds[1]->bdrv);
 | 
					        qdev_prop_set_drive_nofail(&dev->qdev, "driveB", fds[1]->bdrv);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (qdev_init(&dev->qdev) < 0)
 | 
					    qdev_init_nofail(&dev->qdev);
 | 
				
			||||||
        return NULL;
 | 
					 | 
				
			||||||
    return &(DO_UPCAST(FDCtrlISABus, busdev, dev)->state);
 | 
					    return &(DO_UPCAST(FDCtrlISABus, busdev, dev)->state);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1950,9 +1962,7 @@ static int fdctrl_init_common(FDCtrl *fdctrl)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (fdctrl->dma_chann != -1)
 | 
					    if (fdctrl->dma_chann != -1)
 | 
				
			||||||
        DMA_register_channel(fdctrl->dma_chann, &fdctrl_transfer_handler, fdctrl);
 | 
					        DMA_register_channel(fdctrl->dma_chann, &fdctrl_transfer_handler, fdctrl);
 | 
				
			||||||
    fdctrl_connect_drives(fdctrl);
 | 
					    return fdctrl_connect_drives(fdctrl);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int isabus_fdc_init1(ISADevice *dev)
 | 
					static int isabus_fdc_init1(ISADevice *dev)
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user