ide: Update ide_drive_get to be HBA agnostic
Instead of duplicating the logic for the if_ide (bus,unit) mappings, rely on the blockdev layer for managing those mappings for us, and use the drive_get_by_index call instead. This allows ide_drive_get to work for AHCI HBAs as well, and can be used in the Q35 initialization. Lastly, change the nature of the argument to ide_drive_get so that represents the number of total drives we can support, and not the total number of buses. This will prevent array overflows if the units-per-default-bus property ever needs to be adjusted for compatibility reasons. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Message-id: 1412187569-23452-5-git-send-email-jsnow@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
		
							parent
							
								
									1602651833
								
							
						
					
					
						commit
						d8f94e1bb2
					
				
							
								
								
									
										17
									
								
								blockdev.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								blockdev.c
									
									
									
									
									
								
							| @ -135,6 +135,23 @@ void blockdev_auto_del(BlockDriverState *bs) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Returns the current mapping of how many units per bus | ||||
|  * a particular interface can support. | ||||
|  * | ||||
|  *  A positive integer indicates n units per bus. | ||||
|  *  0 implies the mapping has not been established. | ||||
|  * -1 indicates an invalid BlockInterfaceType was given. | ||||
|  */ | ||||
| int drive_get_max_devs(BlockInterfaceType type) | ||||
| { | ||||
|     if (type >= IF_IDE && type < IF_COUNT) { | ||||
|         return if_max_devs[type]; | ||||
|     } | ||||
| 
 | ||||
|     return -1; | ||||
| } | ||||
| 
 | ||||
| static int drive_index_to_bus_id(BlockInterfaceType type, int index) | ||||
| { | ||||
|     int max_devs = if_max_devs[type]; | ||||
|  | ||||
| @ -97,7 +97,7 @@ static void clipper_init(MachineState *machine) | ||||
|     /* IDE disk setup.  */ | ||||
|     { | ||||
|         DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; | ||||
|         ide_drive_get(hd, MAX_IDE_BUS); | ||||
|         ide_drive_get(hd, ARRAY_SIZE(hd)); | ||||
| 
 | ||||
|         pci_cmd646_ide_init(pci_bus, hd, 0); | ||||
|     } | ||||
|  | ||||
| @ -239,7 +239,7 @@ static void pc_init1(MachineState *machine, | ||||
| 
 | ||||
|     pc_nic_init(isa_bus, pci_bus); | ||||
| 
 | ||||
|     ide_drive_get(hd, MAX_IDE_BUS); | ||||
|     ide_drive_get(hd, ARRAY_SIZE(hd)); | ||||
|     if (pci_enabled) { | ||||
|         PCIDevice *dev; | ||||
|         if (xen_enabled()) { | ||||
|  | ||||
| @ -2558,16 +2558,28 @@ const VMStateDescription vmstate_ide_bus = { | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| void ide_drive_get(DriveInfo **hd, int max_bus) | ||||
| void ide_drive_get(DriveInfo **hd, int n) | ||||
| { | ||||
|     int i; | ||||
|     int highest_bus = drive_get_max_bus(IF_IDE) + 1; | ||||
|     int max_devs = drive_get_max_devs(IF_IDE); | ||||
|     int n_buses = max_devs ? (n / max_devs) : n; | ||||
| 
 | ||||
|     if (drive_get_max_bus(IF_IDE) >= max_bus) { | ||||
|         fprintf(stderr, "qemu: too many IDE bus: %d\n", max_bus); | ||||
|     /*
 | ||||
|      * Note: The number of actual buses available is not known. | ||||
|      * We compute this based on the size of the DriveInfo* array, n. | ||||
|      * If it is less than max_devs * <num_real_buses>, | ||||
|      * We will stop looking for drives prematurely instead of overfilling | ||||
|      * the array. | ||||
|      */ | ||||
| 
 | ||||
|     if (highest_bus > n_buses) { | ||||
|         error_report("Too many IDE buses defined (%d > %d)", | ||||
|                      highest_bus, n_buses); | ||||
|         exit(1); | ||||
|     } | ||||
| 
 | ||||
|     for(i = 0; i < max_bus * MAX_IDE_DEVS; i++) { | ||||
|         hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS); | ||||
|     for (i = 0; i < n; i++) { | ||||
|         hd[i] = drive_get_by_index(IF_IDE, i); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -350,7 +350,7 @@ static void mips_fulong2e_init(MachineState *machine) | ||||
|     pci_bus = bonito_init((qemu_irq *)&(env->irq[2])); | ||||
| 
 | ||||
|     /* South bridge */ | ||||
|     ide_drive_get(hd, MAX_IDE_BUS); | ||||
|     ide_drive_get(hd, ARRAY_SIZE(hd)); | ||||
| 
 | ||||
|     isa_bus = vt82c686b_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 0)); | ||||
|     if (!isa_bus) { | ||||
|  | ||||
| @ -1147,7 +1147,7 @@ void mips_malta_init(MachineState *machine) | ||||
|     pci_bus = gt64120_register(isa_irq); | ||||
| 
 | ||||
|     /* Southbridge */ | ||||
|     ide_drive_get(hd, MAX_IDE_BUS); | ||||
|     ide_drive_get(hd, ARRAY_SIZE(hd)); | ||||
| 
 | ||||
|     piix4_devfn = piix4_init(pci_bus, &isa_bus, 80); | ||||
| 
 | ||||
|  | ||||
| @ -294,7 +294,7 @@ void mips_r4k_init(MachineState *machine) | ||||
|     if (nd_table[0].used) | ||||
|         isa_ne2000_init(isa_bus, 0x300, 9, &nd_table[0]); | ||||
| 
 | ||||
|     ide_drive_get(hd, MAX_IDE_BUS); | ||||
|     ide_drive_get(hd, ARRAY_SIZE(hd)); | ||||
|     for(i = 0; i < MAX_IDE_BUS; i++) | ||||
|         isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i], | ||||
|                      hd[MAX_IDE_DEVS * i], | ||||
|  | ||||
| @ -400,7 +400,7 @@ static void ppc_core99_init(MachineState *machine) | ||||
|     macio_init(macio, pic_mem, escc_bar); | ||||
| 
 | ||||
|     /* We only emulate 2 out of 3 IDE controllers for now */ | ||||
|     ide_drive_get(hd, MAX_IDE_BUS); | ||||
|     ide_drive_get(hd, ARRAY_SIZE(hd)); | ||||
| 
 | ||||
|     macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), | ||||
|                                                         "ide[0]")); | ||||
|  | ||||
| @ -278,7 +278,7 @@ static void ppc_heathrow_init(MachineState *machine) | ||||
|         pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL); | ||||
| 
 | ||||
| 
 | ||||
|     ide_drive_get(hd, MAX_IDE_BUS); | ||||
|     ide_drive_get(hd, ARRAY_SIZE(hd)); | ||||
| 
 | ||||
|     macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO); | ||||
|     dev = DEVICE(macio); | ||||
|  | ||||
| @ -519,7 +519,7 @@ static void ppc_prep_init(MachineState *machine) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     ide_drive_get(hd, MAX_IDE_BUS); | ||||
|     ide_drive_get(hd, ARRAY_SIZE(hd)); | ||||
|     for(i = 0; i < MAX_IDE_BUS; i++) { | ||||
|         isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i], | ||||
|                      hd[2 * i], | ||||
|  | ||||
| @ -864,7 +864,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem, | ||||
|     for(i = 0; i < nb_nics; i++) | ||||
|         pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL); | ||||
| 
 | ||||
|     ide_drive_get(hd, MAX_IDE_BUS); | ||||
|     ide_drive_get(hd, ARRAY_SIZE(hd)); | ||||
| 
 | ||||
|     pci_cmd646_ide_init(pci_bus, hd, 1); | ||||
| 
 | ||||
|  | ||||
| @ -52,6 +52,7 @@ DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit); | ||||
| bool drive_check_orphaned(void); | ||||
| DriveInfo *drive_get_by_index(BlockInterfaceType type, int index); | ||||
| int drive_get_max_bus(BlockInterfaceType type); | ||||
| int drive_get_max_devs(BlockInterfaceType type); | ||||
| DriveInfo *drive_get_next(BlockInterfaceType type); | ||||
| DriveInfo *drive_get_by_blockdev(BlockDriverState *bs); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 John Snow
						John Snow