* [Qemu-devel] Patch for SCSI externals
@ 2006-10-17 18:42 Chuck Brazie
2006-10-17 20:04 ` Paul Brook
0 siblings, 1 reply; 2+ messages in thread
From: Chuck Brazie @ 2006-10-17 18:42 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 177 bytes --]
Here is a path to enable the SCSI disk support in QEMU.
Let me know your thoughts, etc. This is my first time at some open source
updates...
Chuck Brazie
brazie@us.ibm.com
[-- Attachment #2: chuck.patch --]
[-- Type: application/octet-stream, Size: 10551 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-10-13 14:00:53.000000000 -0400
@@ -710,23 +710,18 @@
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_53c895a) {
+ scsi = lsi_scsi_init(pci_bus, -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);
+ }
+ }
+ }//end if SCSI lsi adapter to be initialized
}
-#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-10-09 10:30:32.000000000 -0400
+++ /qemu-new/vl.c 2006-10-17 14:30:17.000000000 -0400
@@ -109,6 +109,8 @@
/* XXX: use a two level table to limit memory usage */
#define MAX_IOPORTS 65536
+#define SCSI_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];
+SCSI_disk_info scsi_disks_info[MAX_SCSI_DISKS];
+int scsi_hba_lsi_53c895a; // Count of scsi disks/cdrom using this lsi adapter
int vga_ram_size;
int bios_size;
static DisplayState display_state;
@@ -3731,7 +3736,84 @@
term_printf(" %s\n", vc->info_str);
}
}
+
+ /* Parse SCSI disk options */
+int scsi_disk_options_init(char disk_options[][SCSI_OPTIONS_SIZE])
+{
+ char buf[256];
+ int id, i, j;
+ scsi_host_adapters temp_adapter;
+
+ for(i = 0; i < MAX_SCSI_DISKS; i++) {
+
+ // Was there a SCSI device specified for sdx=a-g
+ if (scsi_disks_info[i].device_type != SCSI_NONE) {
+
+ // Check for hba adapter specified, default to LSI 53c895a
+ if (get_param_value(buf, sizeof(buf),"adapter",disk_options[i])) {
+ if (!strcmp(buf, "lsi53c895a")) {
+ temp_adapter = SCSI_LSI_53C895A;
+ scsi_hba_lsi_53c895a++;
+ } else {
+ fprintf(stderr, "qemu: Unknown SCSI adapter: %s\n", buf);
+ return -1;
+ }
+ }
+ else { /* no model specified, use default. */
+ temp_adapter = SCSI_LSI_53C895A;
+ scsi_hba_lsi_53c895a++;
+ }
+
+ // Check for SCSI id specified.
+ if (get_param_value(buf, sizeof(buf),"id",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 (scsi_disks_info[i].device_type == SCSI_CDROM) {
+ snprintf(buf, sizeof(buf), "media_%c", i + 'a');
+ } else {
+ snprintf(buf, sizeof(buf), "sd%c", i + 'a');
+ }
+ bs_scsi_table[i] = bdrv_new(buf);
+
+ /* Get image filename from options and then try to open it */
+ if (get_param_value(buf, sizeof(buf),"img",disk_options[i])) {
+ if (bdrv_open(bs_scsi_table[i], buf, 0) < 0) {
+ fprintf(stderr, "qemu: could not open SCSI disk image img='%s'\n",buf);
+ exit(1);
+ }
+ }
+ else {
+ fprintf(stderr, "qemu: SCSI disk image not specified for sd%c \n", i + 'a');
+ exit(1);
+ }
+ }//end if a no SCSI disk was specified
+ }//end for all possible SCSI disks
+
+ return 0;
+}//end int scsi_disk_options_init(const char *str)
+
+
+
/***********************************************************/
/* USB devices */
@@ -5840,6 +5922,8 @@
"-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"
+ "-scsi img=file,sdx=a-g[,id=n][,type=cdrom][,adapter=lsi53c895a] \n"
+ " use 'file' as SCSI disk. Defaults: type=disk,adapter=lsi53c895a,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"
@@ -6012,6 +6096,7 @@
QEMU_OPTION_vnc,
QEMU_OPTION_no_acpi,
QEMU_OPTION_no_reboot,
+ QEMU_OPTION_scsi,
};
typedef struct QEMUOption {
@@ -6083,6 +6168,7 @@
{ "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
{ "smp", HAS_ARG, QEMU_OPTION_smp },
{ "vnc", HAS_ARG, QEMU_OPTION_vnc },
+ { "scsi", HAS_ARG, QEMU_OPTION_scsi},
/* temporary options */
{ "usb", 0, QEMU_OPTION_usb },
@@ -6301,6 +6387,7 @@
int snapshot, linux_boot;
const char *initrd_filename;
const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
+ char scsi_options[MAX_SCSI_DISKS] [SCSI_OPTIONS_SIZE];
const char *kernel_filename, *kernel_cmdline;
DisplayState *ds = &display_state;
int cyls, heads, secs, translation;
@@ -6354,6 +6441,10 @@
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;
+ }
for(i = 0; i < MAX_FD; i++)
fd_filename[i] = NULL;
for(i = 0; i < MAX_DISKS; i++)
@@ -6457,6 +6548,39 @@
cdrom_index = -1;
}
break;
+ case QEMU_OPTION_scsi:
+ {
+ int scsi_index;
+ char buf[20];
+ // Verify that sdx=a-g option was specified
+ if (get_param_value(buf, sizeof(buf), "sdx", optarg)) {
+ if (strlen(buf)== 1 && buf[0] >= 'a' && buf[0] <= 'g') {
+ scsi_index = buf[0] - 'a';
+ // Check if this is a disk or cdrom
+ if (get_param_value(buf, sizeof(buf), "type", optarg)) {
+ if (strcmp(buf, "cdrom") && strcmp(buf,"disk")) {
+ fprintf(stderr, "qemu: type= option for SCSI must be cdrom or disk. %s \n",buf);
+ exit(1);
+ }
+ if (!strcmp(buf,"disk")) {
+ scsi_disks_info[scsi_index].device_type = SCSI_DISK;
+ } else {
+ scsi_disks_info[scsi_index].device_type = SCSI_CDROM;
+ }
+ } else {
+ scsi_disks_info[scsi_index].device_type = SCSI_DISK;
+ }
+ } else{
+ fprintf(stderr, "qemu: sdx= option for SCSI must be one letter from a-g. %s \n",buf);
+ exit(1);
+ }
+ } else {
+ fprintf(stderr, "qemu: missing sdx= option for SCSI \n");
+ exit(1);
+ }
+ pstrcpy(scsi_options[scsi_index], sizeof(scsi_options[0]), optarg);
+ }
+ break;
case QEMU_OPTION_snapshot:
snapshot = 1;
break;
@@ -6844,6 +6968,10 @@
}
}
+ /* open the SCSI virtual block devices, disks or CDRoms */
+ if (scsi_disk_options_init(scsi_options)){
+ exit(1);
+ }
register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
register_savevm("ram", 0, 2, ram_save, ram_load, NULL);
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-10-13 14:00:49.000000000 -0400
@@ -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 {
+ scsi_host_adapters adapter;
+ int id;
+ scsi_devices device_type;
+ } SCSI_disk_info;
+
+#define MAX_SCSI_DISKS 7
+extern BlockDriverState *bs_scsi_table[MAX_SCSI_DISKS];
+extern SCSI_disk_info 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_53c895a; // Count of scsi disks/cdrom using this lsi adapter
/* integratorcp.c */
extern QEMUMachine integratorcp926_machine;
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [Qemu-devel] Patch for SCSI externals
2006-10-17 18:42 [Qemu-devel] Patch for SCSI externals Chuck Brazie
@ 2006-10-17 20:04 ` Paul Brook
0 siblings, 0 replies; 2+ messages in thread
From: Paul Brook @ 2006-10-17 20:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Chuck Brazie
On Tuesday 17 October 2006 19:42, Chuck Brazie wrote:
> Here is a path to enable the SCSI disk support in QEMU.
> Let me know your thoughts, etc. This is my first time at some open source
> updates...
I think it would be better to unify the ide and scsi options. I suggest
something like the -net options:
-disk [file=]<finename>,[type={disk,cdrom}][,id={ide,scsi}[N]]
[,format={raw,qcow,...}]
With the existing options being aliases, eg.
-hda fat:foo => -disk file=foo,type-disk,id=ide0,type=vfat
-cdrom bar => -disk bar,type=cdrom,id=ide2
Then make the device emulation lookup devices by id.
Either that or just implement config file support.
Paul
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2006-10-17 20:04 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-17 18:42 [Qemu-devel] Patch for SCSI externals Chuck Brazie
2006-10-17 20:04 ` Paul Brook
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).