qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] SCSI externals patch revisited


From: Chuck Brazie
Subject: [Qemu-devel] SCSI externals patch revisited
Date: Mon, 11 Dec 2006 15:06:36 -0000
User-agent: Thunderbird 1.5.0.8 (Windows/20061025)

Let me try this again from Thunderbird:

Here is a patch that merges the externals for IDE and SCSI with a --disk
as Paul requested. Let me know if you want different keywords.

Chuck

diff -Nuar -X diff_excludes /hg-qemu/hw/pc.c /qemu-new/hw/pc.c
--- /hg-qemu/hw/pc.c    2006-10-09 10:30:32.000000000 -0400
+++ /qemu-new/hw/pc.c   2006-12-04 13:38:50.000000000 -0500
@@ -710,23 +710,20 @@
     if (i440fx_state) {
         i440fx_init_memory_mappings(i440fx_state);
     }
-#if 0
-    /* ??? Need to figure out some way for the user to
-       specify SCSI devices.  */
     if (pci_enabled) {
         void *scsi;
-        BlockDriverState *bdrv;
-
-        scsi = lsi_scsi_init(pci_bus, -1);
-        bdrv = bdrv_new("scsidisk");
-        bdrv_open(bdrv, "scsi_disk.img", 0);
-        lsi_scsi_attach(scsi, bdrv, -1);
-        bdrv = bdrv_new("scsicd");
-        bdrv_open(bdrv, "scsi_cd.iso", 0);
-        bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
-        lsi_scsi_attach(scsi, bdrv, -1);
+        if (scsi_hba_lsi > 0) {
+            if (!(scsi = lsi_scsi_init(pci_bus, -1))){
+                 exit(1);
+            }
+            for(i = 0; i < MAX_SCSI_DISKS; i++) {
+                if (scsi_disks_info[i].adapter == SCSI_LSI_53C895A &&
+                    scsi_disks_info[i].device_type != SCSI_NONE) {
+                    lsi_scsi_attach(scsi, bs_scsi_table[i], 
scsi_disks_info[i].id);
+                }
+            }
+        }
     }
-#endif
 }
 
 static void pc_init_pci(int ram_size, int vga_ram_size, int boot_device,
diff -Nuar -X diff_excludes /hg-qemu/vl.c /qemu-new/vl.c
--- /hg-qemu/vl.c       2006-11-29 14:34:33.000000000 -0500
+++ /qemu-new/vl.c      2006-12-05 15:12:11.000000000 -0500
@@ -109,6 +109,8 @@
 /* XXX: use a two level table to limit memory usage */
 #define MAX_IOPORTS 65536
 
+#define DISK_OPTIONS_SIZE 256
+
 const char *bios_dir = CONFIG_QEMU_SHAREDIR;
 char phys_ram_file[1024];
 void *ioport_opaque[MAX_IOPORTS];
@@ -119,6 +121,9 @@
 BlockDriverState *bs_table[MAX_DISKS + 1], *fd_table[MAX_FD];
 /* point to the block driver where the snapshots are managed */
 BlockDriverState *bs_snapshots;
+BlockDriverState *bs_scsi_table[MAX_SCSI_DISKS]; 
+SCSIDiskInfo scsi_disks_info[MAX_SCSI_DISKS];
+int scsi_hba_lsi; /* Count of scsi disks/cdrom using this lsi adapter */
 int vga_ram_size;
 int bios_size;
 static DisplayState display_state;
@@ -3736,7 +3741,175 @@
             term_printf("  %s\n", vc->info_str);
     }
 }
- 
+
+ /* Parse IDE and SCSI disk options */
+static int disk_options_init(int num_ide_disks, 
+                             char ide_disk_options[][DISK_OPTIONS_SIZE],
+                             int snapshot,
+                             int num_scsi_disks,
+                             char scsi_disk_options[][DISK_OPTIONS_SIZE],
+                             int cdrom_index,
+                             int cyls, 
+                             int heads, 
+                             int secs, 
+                             int translation
+                             )
+{
+    char buf[256];
+    char dev_name[64];
+    int id, i, j;
+    int cdrom_device;
+    int ide_cdrom_created = 0;
+    int scsi_index;
+    scsi_host_adapters temp_adapter;
+
+    /* Process any IDE disks/cdroms */
+    for (i=0; i< num_ide_disks; i++) {
+
+        for (j=0; j<MAX_DISKS; j++) {
+            if (ide_disk_options[j][0] == '\0') continue;
+
+            if (get_param_value(buf, sizeof(buf),"type",ide_disk_options[j])) {
+                if (!strcmp(buf, "disk") ) {
+                    cdrom_device = 0;
+                }else if (!strcmp(buf, "cdrom") ) {
+                    cdrom_device = 1;
+                    ide_cdrom_created = 1;
+                } else {
+                    fprintf(stderr, "qemu: invalid IDE disk type= value: 
%s\n", buf);
+                    return -1;
+                }
+            }
+            else {
+                cdrom_device = 0;
+            }
+
+            if (cdrom_device) {
+                snprintf(dev_name, sizeof(dev_name), "cdrom%c", i);
+            }else{
+                snprintf(dev_name, sizeof(dev_name), "hd%c", i + 'a');
+            }
+
+            if (!(get_param_value(buf, sizeof(buf),"img",ide_disk_options[j]) 
) ) {
+                fprintf(stderr, "qemu: missing IDE disk img= value.\n");
+                return -1;
+            }
+
+            if (!(bs_table[i] = bdrv_new(dev_name) ) ){
+                fprintf(stderr, "qemu: unable to create new block device 
for:%s\n",dev_name);
+                return -1;
+            }
+
+            if (cdrom_device) {
+                bdrv_set_type_hint(bs_table[i], BDRV_TYPE_CDROM);
+            }
+
+            if (bdrv_open(bs_table[i], buf, snapshot ? BDRV_O_SNAPSHOT : 0) < 
0) {
+                fprintf(stderr, "qemu: could not open hard disk image: '%s'\n",
+                        buf);
+                return -1;
+            }
+            if (i == 0 && cyls != 0) {
+                bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
+                bdrv_set_translation_hint(bs_table[i], translation);
+            }
+            ide_disk_options[j][0] = '\0';
+
+            if (i == cdrom_index) {
+                cdrom_index = -1;
+            }
+            break; /* finished with this IDE device*/
+        }
+    }
+
+    if (cdrom_index >= 0 && (!ide_cdrom_created)) {
+        bs_table[cdrom_index] = bdrv_new("cdrom");
+        bdrv_set_type_hint(bs_table[cdrom_index], BDRV_TYPE_CDROM);
+    }
+
+    for(i = 0; i < num_scsi_disks; i++) {
+
+        temp_adapter = SCSI_LSI_53C895A;
+        scsi_hba_lsi++;
+
+        /*Check for sdx= parameter */
+        if (get_param_value(buf, sizeof(buf), "sdx", scsi_disk_options[i])) {
+            if (buf[0] >= 'a' && buf[0] <= 'g') {
+                scsi_index = buf[0] - 'a';
+            } else{
+                fprintf(stderr, "qemu: sdx= option for SCSI must be one letter 
from a-g. %s \n",buf);
+                exit(1);
+            }
+        } else {
+             scsi_index = 0;
+        }
+
+        /* Check for SCSI id specified. */
+        if (get_param_value(buf, sizeof(buf),"id",scsi_disk_options[i])) {
+            id = strtol(buf, NULL, 0);
+            if (id < 0 || id > 6) {
+                fprintf(stderr, "qemu: SCSI id must be from 0-6: %d\n", id);
+                return -1;
+            }
+            /* Check if id already used */
+            for(j = 0; j < MAX_SCSI_DISKS; j++) {
+                if (scsi_disks_info[j].device_type != SCSI_NONE && 
+                    j != i &&
+                    scsi_disks_info[j].adapter == temp_adapter && 
+                    scsi_disks_info[j].id == id  ) {
+                    fprintf(stderr, "qemu: SCSI id already used: %u\n", id);
+                    return -1;
+                }
+            }
+        } else {
+            id = -1;
+        }
+        scsi_disks_info[i].adapter = temp_adapter;
+        scsi_disks_info[i].id = id;
+
+        if (get_param_value(buf, sizeof(buf),"type",scsi_disk_options[i])) {
+            if (!strcmp(buf, "disk") ) {
+                cdrom_device = 0;
+            }else if (!strcmp(buf, "cdrom") ) {
+                cdrom_device = 1;
+            } else {
+                fprintf(stderr, "qemu: invalid SCSI disk type= value: %s\n", 
buf);
+                return -1;
+            }
+        }
+        else {
+            cdrom_device = 0;
+        }
+
+        if (cdrom_device) {
+            snprintf(dev_name, sizeof(buf), "cdrom%c", scsi_index);
+        } else {
+            snprintf(dev_name, sizeof(buf), "sd%c", scsi_index + 'a');
+        }
+
+        if (!(bs_scsi_table[scsi_index] = bdrv_new(dev_name) ) ){
+            fprintf(stderr, "qemu: unable to create new block device 
for:%s\n",dev_name);
+            return -1;
+        }
+
+        /* Get image filename from options and then try to open it */
+        if (get_param_value(buf, sizeof(buf),"img",scsi_disk_options[i])) {
+            if (bdrv_open(bs_scsi_table[scsi_index], buf, 0) < 0) {
+                fprintf(stderr, "qemu: could not open SCSI disk image 
img='%s'\n",buf);
+                return -1;
+            }
+        }
+        else {
+            fprintf(stderr, "qemu: SCSI disk image not specified for sd%c \n", 
i + 'a');
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+
+
 /***********************************************************/
 /* USB devices */
 
@@ -5845,6 +6018,10 @@
            "-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image\n"
            "-cdrom file     use 'file' as IDE cdrom image (cdrom is ide1 
master)\n"
            "-boot [a|c|d]   boot on floppy (a), hard disk (c) or CD-ROM (d)\n"
+           "-disk ide,img=file[,hdx=a..dd][,type=disk|cdrom] \n"
+           "                defaults are: hdx=a,type=disk \n"
+           "-disk scsi,img=file[,sdx=a..g][,type=disk|cdrom][,id=n]  \n"
+           "                defaults are: sdx=a,type=disk,id='auto assign' \n"
           "-snapshot       write to temporary files instead of disk image 
files\n"
 #ifdef TARGET_I386
            "-no-fd-bootchk  disable boot signature checking for floppy disks\n"
@@ -6017,6 +6194,7 @@
     QEMU_OPTION_vnc,
     QEMU_OPTION_no_acpi,
     QEMU_OPTION_no_reboot,
+    QEMU_OPTION_disk,                 
 };
 
 typedef struct QEMUOption {
@@ -6088,6 +6266,7 @@
     { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
     { "smp", HAS_ARG, QEMU_OPTION_smp },
     { "vnc", HAS_ARG, QEMU_OPTION_vnc },
+    { "disk", HAS_ARG, QEMU_OPTION_disk},  
     
     /* temporary options */
     { "usb", 0, QEMU_OPTION_usb },
@@ -6305,7 +6484,11 @@
     int i, cdrom_index;
     int snapshot, linux_boot;
     const char *initrd_filename;
-    const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
+    const char *fd_filename[MAX_FD]; 
+    char scsi_options[MAX_SCSI_DISKS] [DISK_OPTIONS_SIZE]; 
+    char ide_options[MAX_DISKS] [DISK_OPTIONS_SIZE];
+    int num_ide_disks;
+    int num_scsi_disks;
     const char *kernel_filename, *kernel_cmdline;
     DisplayState *ds = &display_state;
     int cyls, heads, secs, translation;
@@ -6359,10 +6542,19 @@
     register_machines();
     machine = first_machine;
     initrd_filename = NULL;
+    for(i = 0; i < MAX_SCSI_DISKS; i++){  
+        scsi_disks_info[i].device_type = SCSI_NONE;
+        bs_scsi_table[i] = NULL;
+    }
+
+    num_ide_disks = 0;
+    num_scsi_disks = 0;
+
     for(i = 0; i < MAX_FD; i++)
         fd_filename[i] = NULL;
-    for(i = 0; i < MAX_DISKS; i++)
-        hd_filename[i] = NULL;
+    for(i = 0; i < MAX_DISKS; i++){
+        ide_options[i][0] =  '\0';
+    }
     ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
     vga_ram_size = VGA_RAM_SIZE;
     bios_size = BIOS_SIZE;
@@ -6406,7 +6598,16 @@
             break;
         r = argv[optind];
         if (r[0] != '-') {
-            hd_filename[0] = argv[optind++];
+
+        /* Build new disk IDE syntax string */
+        pstrcpy(ide_options[0],
+                14,
+                "hdx=a,img=");
+        /*Add on image filename */
+        pstrcpy(&(ide_options[0][13]),
+                sizeof(ide_options[0])-13,
+                argv[optind++]);
+        num_ide_disks++;
         } else {
             const QEMUOption *popt;
 
@@ -6456,10 +6657,79 @@
             case QEMU_OPTION_hdd:
                 {
                     int hd_index;
+                    static char newIDE_DiskSyntax [][10] = { "hdx=a,img=",
+                                                             "hdx=b,img=",
+                                                             "hdx=c,img=",
+                                                             "hdx=d,img=" };
                     hd_index = popt->index - QEMU_OPTION_hda;
-                    hd_filename[hd_index] = optarg;
-                    if (hd_index == cdrom_index)
-                        cdrom_index = -1;
+                    if (num_ide_disks >= MAX_DISKS){
+                        fprintf(stderr, "qemu: too many IDE disks defined.\n");
+                        exit(1);
+                    }
+                    /* Build new disk IDE syntax string */
+                    pstrcpy(ide_options[hd_index],
+                            11,
+                            newIDE_DiskSyntax[hd_index]);
+                    /* Add on image filename */
+                    pstrcpy(&(ide_options[hd_index][10]),
+                            sizeof(ide_options[0])-10,
+                            optarg);
+                    num_ide_disks++;
+                }
+                break;
+            case QEMU_OPTION_disk: /*Combined IDE and SCSI, for disk and CDROM 
*/
+                {
+                    const char *p_input_char;
+                    char *p_output_string;
+                    char device[64];
+                    int disk_index;
+
+                    p_input_char = optarg;
+                    p_output_string = device;
+                    while (*p_input_char != '\0' && *p_input_char != ',') {
+                        if ((p_output_string - device) < sizeof(device) - 1)
+                            *p_output_string++ = *p_input_char;
+                        p_input_char++;
+                    }
+                    *p_output_string = '\0';
+                    if (*p_input_char == ',')
+                        p_input_char++;
+
+                    if (!strcmp(device, "scsi") ){
+                        if (num_scsi_disks >= MAX_SCSI_DISKS){
+                            fprintf(stderr, "qemu: too many SCSI disks 
defined.\n");
+                            exit(1);
+                        }
+                        pstrcpy(scsi_options[num_scsi_disks],
+                                sizeof(scsi_options[0]),
+                                p_input_char);
+                        num_scsi_disks++;
+                    }
+                    else if (!strcmp(device,"ide") ){
+                        if (num_ide_disks >= MAX_DISKS){
+                            fprintf(stderr, "qemu: too many IDE disks/cdroms 
defined.\n");
+                            exit(1);
+                        }
+                        disk_index = 0; /* default is hda */
+                        if (get_param_value(device, 
sizeof(device),"hdx",p_input_char)) {
+                            if (device[0] >= 'a' && device[0] <= 'd') {
+                                disk_index = device[0] - 'a';
+                            } else {
+                                fprintf(stderr, "qemu: invalid IDE disk hdx= 
value: %s\n", device);
+                                return -1;
+                            }
+                        }
+                        else disk_index=0;
+                        pstrcpy(ide_options[disk_index],
+                                sizeof(ide_options[0]),
+                                p_input_char);
+                        num_ide_disks++;
+                    }
+                    else
+                    {
+                        fprintf(stderr, "qemu: -disk option must specify IDE 
or SCSI: %s \n",device);
+                        exit(1);
+                    }
                 }
                 break;
             case QEMU_OPTION_snapshot:
@@ -6513,8 +6783,22 @@
                 kernel_cmdline = optarg;
                 break;
             case QEMU_OPTION_cdrom:
-                if (cdrom_index >= 0) {
-                    hd_filename[cdrom_index] = optarg;
+                {
+                    char buf[24];
+                    if (num_ide_disks >= MAX_DISKS){
+                        fprintf(stderr, "qemu: too many IDE disks/cdroms 
defined.\n");
+                        exit(1);
+                    }
+                    snprintf(buf, sizeof(buf), "type=cdrom,hdx=%c,img=", 
cdrom_index + 'a');
+                    /* Build new disk IDE syntax string */
+                    pstrcpy(ide_options[cdrom_index],
+                            25,
+                            buf);
+                    /* Add on image filename */
+                    pstrcpy(&(ide_options[cdrom_index][24]),
+                            sizeof(ide_options[0])-24,
+                            optarg);
+                    num_ide_disks++;
                 }
                 break;
             case QEMU_OPTION_boot:
@@ -6752,18 +7036,10 @@
     linux_boot = (kernel_filename != NULL);
         
     if (!linux_boot && 
-        hd_filename[0] == '\0' && 
-        (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
+        num_ide_disks == 0 && 
         fd_filename[0] == '\0')
         help();
     
-    /* boot to floppy or the default cd if no hard disk defined yet */
-    if (num_ide_disks == 0 && boot_device == 'c') {
-        if (fd_filename[0] != '\0')
-            boot_device = 'a';
-        else
-            boot_device = 'd';
-    }
 
     setvbuf(stdout, NULL, _IOLBF, 0);
     
@@ -6799,31 +7075,22 @@
         exit(1);
     }
 
-    /* we always create the cdrom drive, even if no disk is there */
     bdrv_init();
-    if (cdrom_index >= 0) {
-        bs_table[cdrom_index] = bdrv_new("cdrom");
-        bdrv_set_type_hint(bs_table[cdrom_index], BDRV_TYPE_CDROM);
-    }
 
-    /* open the virtual block devices */
-    for(i = 0; i < MAX_DISKS; i++) {
-        if (hd_filename[i]) {
-            if (!bs_table[i]) {
-                char buf[64];
-                snprintf(buf, sizeof(buf), "hd%c", i + 'a');
-                bs_table[i] = bdrv_new(buf);
-            }
-            if (bdrv_open(bs_table[i], hd_filename[i], snapshot ? 
BDRV_O_SNAPSHOT : 0) < 0) {
-                fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
-                        hd_filename[i]);
-                exit(1);
-            }
-            if (i == 0 && cyls != 0) {
-                bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
-                bdrv_set_translation_hint(bs_table[i], translation);
-            }
-        }
+    /* open the virtual block devices, disks or CDRoms */
+    if (disk_options_init(num_ide_disks,ide_options,snapshot,
+                          num_scsi_disks,scsi_options,
+                          cdrom_index,
+                          cyls, heads, secs, translation)){
+        exit(1);
+    }
+    
+    /* boot to floppy or default cd if no hard disk */
+    if (num_ide_disks == 0 && boot_device == 'c') {
+        if (fd_filename[0] != '\0')
+            boot_device = 'a';
+        else
+            boot_device = 'd';
     }
 
     /* we always create at least one floppy disk */
diff -Nuar -X diff_excludes /hg-qemu/vl.h /qemu-new/vl.h
--- /hg-qemu/vl.h       2006-10-09 10:30:32.000000000 -0400
+++ /qemu-new/vl.h      2006-12-04 10:38:01.000000000 -0500
@@ -1217,9 +1217,30 @@
 void scsi_cancel_io(SCSIDevice *s, uint32_t tag);
 uint8_t *scsi_get_buf(SCSIDevice *s, uint32_t tag);
 
+enum scsi_host_adapters {           
+    SCSI_LSI_53C895A
+};
+enum scsi_devices {          
+    SCSI_CDROM,
+    SCSI_DISK,
+    SCSI_NONE
+};
+typedef enum scsi_host_adapters scsi_host_adapters;
+typedef enum scsi_devices scsi_devices;
+typedef struct SCSIDiskInfo{
+    scsi_host_adapters adapter; 
+    int id;
+    scsi_devices device_type;
+    } SCSIDiskInfo;
+
+#define MAX_SCSI_DISKS 7
+extern BlockDriverState *bs_scsi_table[MAX_SCSI_DISKS];
+extern SCSIDiskInfo scsi_disks_info[MAX_SCSI_DISKS];
+
 /* lsi53c895a.c */
 void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id);
 void *lsi_scsi_init(PCIBus *bus, int devfn);
+extern int scsi_hba_lsi; // Count of scsi disks/cdrom using this lsi adapter 
 
 /* integratorcp.c */
 extern QEMUMachine integratorcp926_machine;


reply via email to

[Prev in Thread] Current Thread [Next in Thread]