qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] SCSI externals patch revisited
@ 2006-12-08 15:16 Chuck Brazie
  0 siblings, 0 replies; 11+ messages in thread
From: Chuck Brazie @ 2006-12-08 15:16 UTC (permalink / raw)
  To: QEMU-devel

[-- Attachment #1: Type: text/plain, Size: 144 bytes --]

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

[-- Attachment #2: scsiExternals.patch --]
[-- Type: text/plain, Size: 19462 bytes --]

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;

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Qemu-devel] SCSI externals patch revisited
@ 2006-12-11 12:33 Chuck Brazie
  2006-12-11 13:34 ` Thiemo Seufer
  0 siblings, 1 reply; 11+ messages in thread
From: Chuck Brazie @ 2006-12-11 12:33 UTC (permalink / raw)
  To: qemu-devel

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 Brazie 
brazie@us.ibm.com

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;

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] SCSI externals patch revisited
  2006-12-11 12:33 Chuck Brazie
@ 2006-12-11 13:34 ` Thiemo Seufer
  0 siblings, 0 replies; 11+ messages in thread
From: Thiemo Seufer @ 2006-12-11 13:34 UTC (permalink / raw)
  To: Chuck Brazie; +Cc: qemu-devel

Chuck Brazie wrote:
> 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. 

I want a patch which wasn't mangled by a broken mail program. :-)


Thiemo

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Qemu-devel] SCSI externals patch revisited
@ 2006-12-11 15:06 Chuck Brazie
  0 siblings, 0 replies; 11+ messages in thread
From: Chuck Brazie @ 2006-12-11 15:06 UTC (permalink / raw)
  To: QEMU-devel

[-- Attachment #1: Type: text/plain, Size: 185 bytes --]

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


[-- Attachment #2: scsiExternals.patch --]
[-- Type: text/plain, Size: 19463 bytes --]

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;


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Qemu-devel] SCSI externals [PATCH] revisited
@ 2006-12-12 12:02 Chuck Brazie
  2006-12-12 12:11 ` Hetz Ben Hamo
  2006-12-12 23:42 ` [Qemu-devel] " Russell Jackson
  0 siblings, 2 replies; 11+ messages in thread
From: Chuck Brazie @ 2006-12-12 12:02 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 187 bytes --]

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




[-- Attachment #2: scsiExternals.patch --]
[-- Type: text/plain, Size: 19464 bytes --]

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;



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] SCSI externals [PATCH] revisited
  2006-12-12 12:02 [Qemu-devel] SCSI externals [PATCH] revisited Chuck Brazie
@ 2006-12-12 12:11 ` Hetz Ben Hamo
  2006-12-12 15:15   ` [Qemu-devel] " Anthony Liguori
  2006-12-12 23:42 ` [Qemu-devel] " Russell Jackson
  1 sibling, 1 reply; 11+ messages in thread
From: Hetz Ben Hamo @ 2006-12-12 12:11 UTC (permalink / raw)
  To: qemu-devel

Chuck,

IMHO, in order to be able to use such patches as yours (big patches),
I think it would be the best to attached them as compressed files
(gzip, bz2).
That way, almost any mailer knows how to handle attachment without
scrambling the patch formatting

Thanks,
Hetz

On 12/12/06, Chuck Brazie <cbrazie@stny.rr.com> wrote:
> 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;
>
>
>
>
> _______________________________________________
> Qemu-devel mailing list
> Qemu-devel@nongnu.org
> http://lists.nongnu.org/mailman/listinfo/qemu-devel
>
>
>


-- 
Visit my blog (hebrew) for things that (sometimes) matter:
 http://wp.dad-answers.com

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Qemu-devel] Re: SCSI externals [PATCH] revisited
  2006-12-12 12:11 ` Hetz Ben Hamo
@ 2006-12-12 15:15   ` Anthony Liguori
  2006-12-12 17:39     ` RE : " Sylvain Petreolle
  0 siblings, 1 reply; 11+ messages in thread
From: Anthony Liguori @ 2006-12-12 15:15 UTC (permalink / raw)
  To: qemu-devel

Hetz Ben Hamo wrote:
> Chuck,
> 
> IMHO, in order to be able to use such patches as yours (big patches),
> I think it would be the best to attached them as compressed files
> (gzip, bz2).

Ugh.  It's a text plain attachment.  No mailers will scramble that.  A 
lot of mailing lists will drop any non text/plain attachments to prevent 
works so compressing is probably not a good idea.  If the patch is 
really really big, pointing to an external URL would probably work best.

The problem with the previous patch was Lotus Notes.  Lotus is a bit 
brain dead when it comes to sending attachments (it really sends mail 
via a special format and then converts it to rfc822).  The result is 
that all attachments are application/octet-stream.

Regards,

Anthony Liguori

> That way, almost any mailer knows how to handle attachment without
> scrambling the patch formatting
> 
> Thanks,
> Hetz

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE : [Qemu-devel] Re: SCSI externals [PATCH] revisited
  2006-12-12 15:15   ` [Qemu-devel] " Anthony Liguori
@ 2006-12-12 17:39     ` Sylvain Petreolle
  0 siblings, 0 replies; 11+ messages in thread
From: Sylvain Petreolle @ 2006-12-12 17:39 UTC (permalink / raw)
  To: qemu-devel


--- Anthony Liguori <anthony@codemonkey.ws> a écrit :

> Hetz Ben Hamo wrote:
> > Chuck,
> > 
> > IMHO, in order to be able to use such patches as yours (big patches),
> > I think it would be the best to attached them as compressed files
> > (gzip, bz2).
> 
> Ugh.  It's a text plain attachment.  No mailers will scramble that.  A 
> lot of mailing lists will drop any non text/plain attachments to prevent 
> works so compressing is probably not a good idea.  If the patch is 
> really really big, pointing to an external URL would probably work best.
> 
I have to disagree here, many mailers do scramble text attachments,
especially with long lines and TABs / special characters.

Kind regards,
Sylvain Petreolle (aka Usurp)
--- --- --- --- --- --- --- --- --- --- --- --- ---
Run your favorite Windows apps with free ReactOS : http://www.reactos.org
Listen to non-DRMised Music: http://www.jamendo.com

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] SCSI externals [PATCH] revisited
  2006-12-12 12:02 [Qemu-devel] SCSI externals [PATCH] revisited Chuck Brazie
  2006-12-12 12:11 ` Hetz Ben Hamo
@ 2006-12-12 23:42 ` Russell Jackson
  2006-12-12 23:57   ` Daniel Stekloff
  1 sibling, 1 reply; 11+ messages in thread
From: Russell Jackson @ 2006-12-12 23:42 UTC (permalink / raw)
  To: qemu-devel

On Tue, Dec 12, 2006 at 07:02:33AM -0500, Chuck Brazie wrote:
> 
> 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.
> 

I was able to apply the patch (almost) cleanly to a November snapshot.
The following invocation results in the LSI controller showing up in
Windows XP, but the disk(s) do not. Am I missing something?

qemu -kernel-kqemu -localtime -std-vga \
	-disk ide,img=winxp.qcow \
	-disk scsi,img=test.qcow

It doesn't seem possible to boot from a SCSI disk currently. In fact,
there's a check in vl.c to see if there is at least one IDE disk that
just dumps the usage output without an error which was rather confusing
:-P. I'm thinking that the emulated BIOS doesn't support SCSI yet?

-- 
Russell A. Jackson <raj@csub.edu>
Network Analyst
California State University, Bakersfield

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] SCSI externals [PATCH] revisited
  2006-12-12 23:42 ` [Qemu-devel] " Russell Jackson
@ 2006-12-12 23:57   ` Daniel Stekloff
  2006-12-13  0:06     ` Russell Jackson
  0 siblings, 1 reply; 11+ messages in thread
From: Daniel Stekloff @ 2006-12-12 23:57 UTC (permalink / raw)
  To: qemu-devel

On Tue, 2006-12-12 at 15:42 -0800, Russell Jackson wrote:
> On Tue, Dec 12, 2006 at 07:02:33AM -0500, Chuck Brazie wrote:
> >
> > 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.
> >
> 
> I was able to apply the patch (almost) cleanly to a November snapshot.
> The following invocation results in the LSI controller showing up in
> Windows XP, but the disk(s) do not. Am I missing something?
> 
> qemu -kernel-kqemu -localtime -std-vga \
> 	-disk ide,img=winxp.qcow \
> 	-disk scsi,img=test.qcow


Is your test.qcow formatted? I had to go into the Windows admin
utilities and format the disk before it became available. 


> It doesn't seem possible to boot from a SCSI disk currently. In fact,
> there's a check in vl.c to see if there is at least one IDE disk that
> just dumps the usage output without an error which was rather confusing
> :-P. I'm thinking that the emulated BIOS doesn't support SCSI yet?


Yep, no support currently for booting off SCSI. 

Thanks,

Dan

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] SCSI externals [PATCH] revisited
  2006-12-12 23:57   ` Daniel Stekloff
@ 2006-12-13  0:06     ` Russell Jackson
  0 siblings, 0 replies; 11+ messages in thread
From: Russell Jackson @ 2006-12-13  0:06 UTC (permalink / raw)
  To: qemu-devel

On Tue, Dec 12, 2006 at 03:57:36PM -0800, Daniel Stekloff wrote:
> > I was able to apply the patch (almost) cleanly to a November snapshot.
> > The following invocation results in the LSI controller showing up in
> > Windows XP, but the disk(s) do not. Am I missing something?
> > 
> > qemu -kernel-kqemu -localtime -std-vga \
> > 	-disk ide,img=winxp.qcow \
> > 	-disk scsi,img=test.qcow
> 
> 
> Is your test.qcow formatted? I had to go into the Windows admin
> utilities and format the disk before it became available. 
> 
> 

Well that's the problem; I can't format it. SCSI devices don't show up
in the disk management console at all.

-- 
Russell A. Jackson <raj@csub.edu>
Network Analyst
California State University, Bakersfield

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2006-12-13  0:06 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-12 12:02 [Qemu-devel] SCSI externals [PATCH] revisited Chuck Brazie
2006-12-12 12:11 ` Hetz Ben Hamo
2006-12-12 15:15   ` [Qemu-devel] " Anthony Liguori
2006-12-12 17:39     ` RE : " Sylvain Petreolle
2006-12-12 23:42 ` [Qemu-devel] " Russell Jackson
2006-12-12 23:57   ` Daniel Stekloff
2006-12-13  0:06     ` Russell Jackson
  -- strict thread matches above, loose matches on Subject: below --
2006-12-11 15:06 [Qemu-devel] SCSI externals patch revisited Chuck Brazie
2006-12-11 12:33 Chuck Brazie
2006-12-11 13:34 ` Thiemo Seufer
2006-12-08 15:16 Chuck Brazie

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).