qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 2/7] Add scsi support for the target PC


From: Laurent Vivier
Subject: [Qemu-devel] [PATCH 2/7] Add scsi support for the target PC
Date: Wed, 31 Oct 2007 16:51:52 +0100

This patch adds the SCSI support for the target PC.
It allows to initalize SCSI interface in the PC init machine.

it adds a new interface type "scsi" to "-disk" interface.

"-disk file,if=scsi,bus=0,unit=6" allows to connect the disk image file to the
bus 0 with the unit id 6.

if there is no SCSI disk, the SCSI interface is not created.

It also defines the default interface type to "scsi" for targets 
"realview", "SS-5", "SS-10", "versatilepb", "versatileab"
to keep old behavior, where "-hda" is a SCSI disk.

--
 hw/esp.c         |    4 +-
 hw/pc.c          |   30 ++++++++-------
 hw/realview.c    |    6 +--
 hw/sun4m.c       |    6 +--
 hw/versatilepb.c |    6 +--
 monitor.c        |    7 +++
 vl.c             |  108 +++++++++++++++++++++++++++++++++++++++++++++++++------
 vl.h             |    9 ++++
 8 files changed, 139 insertions(+), 37 deletions(-)

Index: qemu/hw/pc.c
===================================================================
--- qemu.orig/hw/pc.c   2007-10-31 14:13:20.000000000 +0100
+++ qemu/hw/pc.c        2007-10-31 14:23:52.000000000 +0100
@@ -927,23 +927,25 @@
     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;
+        void *scsi[SCSI_MAX_BUS];
+       int max_bus = -1;
+
+       for (i = 0; i < MAX_SCSI_DISKS; i++)
+           if (sd_table[i])
+               max_bus = i / SCSI_MAX_DEVS + 1;
+
+       for (i = 0; i < max_bus; i++)
+            scsi[i] = lsi_scsi_init(pci_bus, -1);
 
-        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);
+       for (i = 0; i < MAX_SCSI_DISKS; i++) {
+           if (sd_table[i]) {
+                lsi_scsi_attach(scsi[i / SCSI_MAX_DEVS],
+                               sd_table[i], i % SCSI_MAX_DEVS);
+           }
+        }
     }
-#endif
 }
 
 static void pc_init_pci(int ram_size, int vga_ram_size, const char 
*boot_device,
Index: qemu/hw/realview.c
===================================================================
--- qemu.orig/hw/realview.c     2007-10-31 14:12:40.000000000 +0100
+++ qemu/hw/realview.c  2007-10-31 14:23:52.000000000 +0100
@@ -65,9 +65,9 @@
         usb_ohci_init_pci(pci_bus, 3, -1);
     }
     scsi_hba = lsi_scsi_init(pci_bus, -1);
-    for (n = 0; n < MAX_DISKS; n++) {
-        if (bs_table[n]) {
-            lsi_scsi_attach(scsi_hba, bs_table[n], n);
+    for (n = 0; n < SCSI_MAX_DEVS; n++) {
+        if (sd_table[n]) {
+            lsi_scsi_attach(scsi_hba, sd_table[n], n);
         }
     }
     for(n = 0; n < nb_nics; n++) {
Index: qemu/hw/versatilepb.c
===================================================================
--- qemu.orig/hw/versatilepb.c  2007-10-31 14:12:40.000000000 +0100
+++ qemu/hw/versatilepb.c       2007-10-31 14:23:52.000000000 +0100
@@ -199,9 +199,9 @@
         usb_ohci_init_pci(pci_bus, 3, -1);
     }
     scsi_hba = lsi_scsi_init(pci_bus, -1);
-    for (n = 0; n < MAX_DISKS; n++) {
-        if (bs_table[n]) {
-            lsi_scsi_attach(scsi_hba, bs_table[n], n);
+    for (n = 0; n < SCSI_MAX_DEVS; n++) {
+        if (sd_table[n]) {
+            lsi_scsi_attach(scsi_hba, sd_table[n], n);
         }
     }
 
Index: qemu/vl.c
===================================================================
--- qemu.orig/vl.c      2007-10-31 14:18:25.000000000 +0100
+++ qemu/vl.c   2007-10-31 14:23:52.000000000 +0100
@@ -152,6 +152,7 @@
 /* Note: bs_table[MAX_IDE_DISKS] is a dummy block driver if none available
    to store the VM snapshots */
 BlockDriverState *bs_table[MAX_IDE_DISKS + 1], *fd_table[MAX_FD];
+BlockDriverState *sd_table[MAX_SCSI_DISKS + 1];
 BlockDriverState *pflash_table[MAX_PFLASH];
 BlockDriverState *sd_bdrv;
 BlockDriverState *mtd_bdrv;
@@ -1752,6 +1753,10 @@
                     if (bs_table[i])
                         bdrv_commit(bs_table[i]);
                 }
+                for (i = 0; i < MAX_SCSI_DISKS; i++) {
+                    if (sd_table[i])
+                        bdrv_commit(sd_table[i]);
+                }
                 if (mtd_bdrv)
                     bdrv_commit(mtd_bdrv);
             }
@@ -4714,7 +4719,7 @@
 #define CDROM_ALIAS ",index=2,media=cdrom"
 #endif
 
-static int disk_init(const char *str, int snapshot)
+static int disk_init(const char *str, int snapshot, QEMUMachine *machine)
 {
     char buf[16];
     enum { IF_IDE, IF_SCSI } interface;
@@ -4739,7 +4744,16 @@
     unit_id = -1;
     disk_index = -1;
     translation = BIOS_ATA_TRANSLATION_AUTO;
-    interface = IF_IDE;
+
+    if (!strcmp(machine->name, "realview") ||
+        !strcmp(machine->name, "SS-5") ||
+        !strcmp(machine->name, "SS-10") ||
+        !strcmp(machine->name, "versatilepb") ||
+        !strcmp(machine->name, "versatileab")) {
+        interface = IF_SCSI;
+    } else {
+        interface = IF_IDE;
+    }
     media = MEDIA_DISK;
 
     /* extract parameters */
@@ -4899,8 +4913,59 @@
        }
         break;
     case IF_SCSI:
-        /* TODO */
-       break;
+
+       if (bus_id >= SCSI_MAX_BUS) {
+            fprintf(stderr, "qemu: bus id too big\n");
+           return -1;
+        }
+
+       if (unit_id >= SCSI_MAX_DEVS) {
+            fprintf(stderr, "qemu: unit id too big\n");
+           return -1;
+        }
+
+       if (bus_id != -1 && unit_id != -1)
+           disk_index = bus_id * SCSI_MAX_DEVS + unit_id;
+       else {
+           if (bus_id != -1)
+               disk_index = bus_id * SCSI_MAX_DEVS;
+           else
+               disk_index = 0;
+            while (sd_table[disk_index] && disk_index < SCSI_MAX_DEVS)
+                disk_index++;
+       }
+       if (disk_index >= MAX_SCSI_DISKS) {
+           fprintf(stderr, "qemu: too many disks\n");
+           return -1;
+       }
+
+        if (!sd_table[disk_index]) {
+            switch(media) {
+           case MEDIA_DISK:
+                snprintf(buf, sizeof(buf), "sd%c", disk_index + 'a');
+                sd_table[disk_index] = bdrv_new(buf);
+               break;
+           case MEDIA_CDROM:
+                snprintf(buf, sizeof(buf), "sr%c", disk_index + '0');
+                sd_table[disk_index] = bdrv_new(buf);
+                bdrv_set_type_hint(sd_table[disk_index], BDRV_TYPE_CDROM);
+               break;
+           }
+
+            if (file[0] && bdrv_open(sd_table[disk_index], file,
+                          snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
+                fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
+                        file);
+                      return -1;
+            }
+
+            if (cyls != 0) {
+                bdrv_set_geometry_hint(sd_table[disk_index],
+                                      cyls, heads, secs);
+                bdrv_set_translation_hint(sd_table[disk_index], translation);
+            }
+       }
+        break;
     }
    return 0;
 }
@@ -5693,6 +5758,11 @@
         if (bdrv_can_snapshot(bs))
             goto ok;
     }
+    for(i = 0; i <= MAX_SCSI_DISKS; i++) {
+        bs = sd_table[i];
+        if (bdrv_can_snapshot(bs))
+            goto ok;
+    }
     return NULL;
  ok:
     bs_snapshots = bs;
@@ -5797,8 +5867,11 @@
 
     /* create the snapshots */
 
-    for(i = 0; i < MAX_IDE_DISKS; i++) {
-        bs1 = bs_table[i];
+    for(i = 0; i < MAX_IDE_DISKS + MAX_SCSI_DISKS; i++) {
+       if (i < MAX_IDE_DISKS)
+            bs1 = bs_table[i];
+       else
+            bs1 = sd_table[i - MAX_IDE_DISKS];
         if (bdrv_has_snapshot(bs1)) {
             if (must_delete) {
                 ret = bdrv_snapshot_delete(bs1, old_sn->id_str);
@@ -5840,8 +5913,11 @@
     saved_vm_running = vm_running;
     vm_stop(0);
 
-    for(i = 0; i <= MAX_IDE_DISKS; i++) {
-        bs1 = bs_table[i];
+    for(i = 0; i <= MAX_IDE_DISKS + MAX_SCSI_DISKS; i++) {
+       if (i < MAX_IDE_DISKS)
+            bs1 = bs_table[i];
+       else
+            bs1 = sd_table[i - MAX_IDE_DISKS];
         if (bdrv_has_snapshot(bs1)) {
             ret = bdrv_snapshot_goto(bs1, name);
             if (ret < 0) {
@@ -5901,8 +5977,11 @@
         return;
     }
 
-    for(i = 0; i <= MAX_IDE_DISKS; i++) {
-        bs1 = bs_table[i];
+    for(i = 0; i <= MAX_IDE_DISKS + MAX_SCSI_DISKS; i++) {
+       if (i < MAX_IDE_DISKS)
+            bs1 = bs_table[i];
+       else
+            bs1 = sd_table[i - MAX_IDE_DISKS];
         if (bdrv_has_snapshot(bs1)) {
             ret = bdrv_snapshot_delete(bs1, name);
             if (ret < 0) {
@@ -5937,6 +6016,13 @@
                 term_printf(" %s", bdrv_get_device_name(bs1));
         }
     }
+    for(i = 0; i <= MAX_SCSI_DISKS; i++) {
+        bs1 = sd_table[i];
+        if (bdrv_has_snapshot(bs1)) {
+            if (bs == bs1)
+                term_printf(" %s", bdrv_get_device_name(bs1));
+        }
+    }
     term_printf("\n");
 
     nb_sns = bdrv_snapshot_list(bs, &sn_tab);
@@ -8523,7 +8609,7 @@
     /* open the virtual block devices */
 
     for(i = 0; i < nb_disks; i++)
-        if (disk_init(disks[i], snapshot) == -1)
+        if (disk_init(disks[i], snapshot, machine) == -1)
            exit(1);
 
     /* we always create at least one floppy disk */
Index: qemu/vl.h
===================================================================
--- qemu.orig/vl.h      2007-10-31 14:13:20.000000000 +0100
+++ qemu/vl.h   2007-10-31 14:23:52.000000000 +0100
@@ -983,14 +983,21 @@
 /* x_keymap.c */
 extern uint8_t _translate_keycode(const int key);
 
+/* lsi53c895a.c */
+
+#define SCSI_MAX_DEVS 7
+#define SCSI_MAX_BUS 4
+#define MAX_SCSI_DISKS (SCSI_MAX_BUS * SCSI_MAX_DEVS)
+
 /* ide.c */
 #define MAX_IDE_BUS 2
 #define MAX_IDE_DEVS 2
 #define MAX_IDE_DISKS (MAX_IDE_BUS * MAX_IDE_DEVS)
 
-#define MAX_DISKS (MAX_IDE_DISKS)
+#define MAX_DISKS (MAX_IDE_DISKS + MAX_SCSI_DISKS)
 
 extern BlockDriverState *bs_table[MAX_IDE_DISKS + 1];
+extern BlockDriverState *sd_table[MAX_SCSI_DISKS + 1];
 extern BlockDriverState *sd_bdrv;
 extern BlockDriverState *mtd_bdrv;
 
Index: qemu/hw/sun4m.c
===================================================================
--- qemu.orig/hw/sun4m.c        2007-10-31 14:12:40.000000000 +0100
+++ qemu/hw/sun4m.c     2007-10-31 14:23:52.000000000 +0100
@@ -394,9 +394,9 @@
     main_esp = esp_init(bs_table, hwdef->esp_base, espdma, *espdma_irq,
                         esp_reset);
 
-    for (i = 0; i < MAX_DISKS; i++) {
-        if (bs_table[i]) {
-            esp_scsi_attach(main_esp, bs_table[i], i);
+    for (i = 0; i < MAX_SCSI_DISKS; i++) {
+        if (sd_table[i]) {
+            esp_scsi_attach(main_esp, sd_table[i], i);
         }
     }
 
Index: qemu/monitor.c
===================================================================
--- qemu.orig/monitor.c 2007-10-31 14:13:20.000000000 +0100
+++ qemu/monitor.c      2007-10-31 14:23:52.000000000 +0100
@@ -211,6 +211,13 @@
                 bdrv_commit(bs_table[i]);
         }
     }
+    for (i = 0; i < MAX_SCSI_DISKS; i++) {
+        if (sd_table[i]) {
+            if (all_devices ||
+                !strcmp(bdrv_get_device_name(sd_table[i]), device))
+                bdrv_commit(sd_table[i]);
+        }
+    }
     if (mtd_bdrv)
         if (all_devices || !strcmp(bdrv_get_device_name(mtd_bdrv), device))
             bdrv_commit(mtd_bdrv);
Index: qemu/hw/esp.c
===================================================================
--- qemu.orig/hw/esp.c  2007-10-31 14:12:18.000000000 +0100
+++ qemu/hw/esp.c       2007-10-31 14:23:52.000000000 +0100
@@ -60,7 +60,7 @@
     uint8_t ti_buf[TI_BUFSZ];
     int sense;
     int dma;
-    SCSIDevice *scsi_dev[MAX_DISKS];
+    SCSIDevice *scsi_dev[SCSI_MAX_DEVS];
     SCSIDevice *current_dev;
     uint8_t cmdbuf[TI_BUFSZ];
     int cmdlen;
@@ -122,7 +122,7 @@
         s->async_len = 0;
     }
 
-    if (target >= MAX_DISKS || !s->scsi_dev[target]) {
+    if (target >= SCSI_MAX_DEVS || !s->scsi_dev[target]) {
         // No such drive
         s->rregs[4] = STAT_IN;
         s->rregs[5] = INTR_DC;





reply via email to

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