From: risc@volumehost.com
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] -disk patch
Date: Tue, 24 Jul 2007 16:30:01 -0500 [thread overview]
Message-ID: <20070724213001.GT4797@volumehost.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 935 bytes --]
Lets try this again. (forgot to attach patch! )
the attached patch is a re-hash of the old "-disk" patch against current CVS.
things it does(on X86):
adds a "-disk scsi,hba=ADAPTER_NO,id=SCSI_ID,img=DISK_IMAGE,type=disk" syntax, for specifying scsi devices.
supports the old -hd[a-d] arguments.
supports using -cdrom twice, creating two cdrom devices on the second IDE channel.
supports multiple adapters. i coded for four, but can only get 3 working under linux, due to the driver in linux not supporting sharing the IRQ.
things it dosent do:
bochbios and linuxbios don't support booting off of a scsi disk.
-cdrom can't create a device on the primary controller. i'm suspecting irq routing, or somesuch.
the scsi driver still dosent support devices [8..15].
with this patch, i'm running a qemu session with one IDE disk, two cdroms, and 21[!] scsi disks.
comments, suggestions, etc welcome.
Julia Longtin <risc@volumehost.com>
[-- Attachment #2: 67_scsi.patch --]
[-- Type: text/plain, Size: 22174 bytes --]
--- hw/pc.c.orig 2006-10-09 10:30:32.000000000 -0400
+++ hw/pc.c 2007-06-30 13:38:50.000000000 -0500
@@ -913,23 +913,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[MAX_SCSI_CONTROLLERS];;
+ int id, hba;
- 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_disks > 0) {
+ for (i=0; i<scsi_hba_lsi; i++) {
+ if (!(scsi[i] = lsi_scsi_init(pci_bus, -1))){
+ exit(1);
+ }
+ }
+ for (i=0; i<MAX_SCSI_DISKS; i++) {
+ if (bs_scsi_table[i]!=NULL) {
+ id=scsi_disks_info[i].id;
+ hba=scsi_disks_info[i].hba;
+ lsi_scsi_attach(scsi[hba], bs_scsi_table[i],id);
+ }
+ }
+ }
}
-#endif
}
static void pc_init_pci(int ram_size, int vga_ram_size, int boot_device,
--- vl.c.orig 2006-11-29 14:34:33.000000000 -0500
+++ vl.c 2006-12-05 15:12:11.000000000 -0500
@@ -132,6 +132,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];
@@ -145,6 +147,12 @@
BlockDriverState *mtd_bdrv;
/* 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 lsi adapters */
+int scsi_disks; /* Count of scsi disks and cdroms */
+int cdrom_drives; /* Count of total cdroms */
+int first_bootable_cdrom; /* cdrom drive to boot off of */
int vga_ram_size;
static DisplayState display_state;
int nographic;
@@ -4304,7 +4309,184 @@
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 cyls,
+ int heads,
+ int secs,
+ int translation
+ )
+{
+ char buf[256];
+ char dev_name[64];
+ int id, hba, i, j;
+ int cdrom_device;
+ scsi_host_adapters temp_adapter;
+
+ /* Process any IDE devices */
+
+ if (num_ide_disks>MAX_DISKS) {
+ fprintf(stderr,"too many ide disks. called with %d, MAX_DISKS is set to %d\n",num_ide_disks,MAX_DISKS);
+ return -1;
+ }
+
+ for (i=0; i<MAX_DISKS; i++) {
+
+ if (ide_disk_options[i][0] == '\0') {
+ bs_table[i]=NULL;
+ continue;
+ }
+
+ if (get_param_value(buf, sizeof(buf),"type",ide_disk_options[i])) {
+ if (!strcmp(buf, "disk") ) {
+ cdrom_device = 0;
+ }else if (!strcmp(buf, "cdrom") ) {
+ cdrom_device = 1;
+ } else {
+ fprintf(stderr, "qemu: invalid IDE device type= value: %s\n", buf);
+ return -1;
+ }
+ }
+ else {
+ cdrom_device = 0;
+ }
+
+ if (!(get_param_value(buf, sizeof(buf),"hdx",ide_disk_options[i]) ) ) {
+ fprintf(stderr, "qemu: missing IDE device hdx= value.\n");
+ return -1;
+ }
+
+ /* cdrom device naming takes into account both ide and scsi cdroms. */
+ if (cdrom_device) {
+ snprintf(dev_name, sizeof(dev_name), "cdrom%c", cdrom_drives+'0');
+ cdrom_drives++;
+ if (first_bootable_cdrom == 0) {
+ first_bootable_cdrom = buf[0];
+ }
+ } else {
+ snprintf(dev_name, sizeof(dev_name), "hd%c", buf[0]);
+ }
+ if (!(get_param_value(buf, sizeof(buf),"img",ide_disk_options[i]) ) ) {
+ fprintf(stderr, "qemu: missing IDE device img= value on device %s.\n",dev_name);
+ fprintf(stderr, "qemu: ide device string given: %s\n",ide_disk_options[i]);
+ return -1;
+ }
+
+ fprintf(stderr,"associating file %s to device %s\n",buf,dev_name);
+ 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 (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 (cdrom_device) {
+ bdrv_set_type_hint(bs_table[i], BDRV_TYPE_CDROM);
+ }
+
+ if (i == 0 && cyls != 0) {
+ bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
+ bdrv_set_translation_hint(bs_table[i], translation);
+ }
+ }
+
+ for(i = 0; i < MAX_SCSI_DISKS; i++) {
+
+ temp_adapter = SCSI_LSI_53C895A;
+ if (scsi_disk_options[i][0]==NULL) { continue; }
+ scsi_disks++;
+
+ /* Check for SCSI id specified. */
+ if (get_param_value(buf, sizeof(buf),"hba",scsi_disk_options[i])) {
+ hba = strtol(buf, NULL, 0);
+ if (hba<0 || hba>(MAX_SCSI_CONTROLLERS-1)) {
+ fprintf(stderr, "qemu: SCSI hba must be from 0-%d\n", MAX_SCSI_CONTROLLERS-1);
+ return -1;
+ }
+ }
+ else hba=0;
+ if (hba+1>scsi_hba_lsi) { scsi_hba_lsi=hba+1; }
+ 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].hba == hba &&
+ scsi_disks_info[j].id == id ) {
+ fprintf(stderr, "qemu: SCSI id already used: %d\n", id);
+ return -1;
+ }
+ }
+ } else {
+ fprintf(stderr,"qemu: id for scsi device %d not specified.",i);
+ return -1;
+ }
+ scsi_disks_info[i].adapter = temp_adapter;
+ scsi_disks_info[i].hba = hba;
+ 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;
+ }
+
+ /* cdrom device naming takes into account both ide and scsi cdroms. */
+ if (cdrom_device) {
+ snprintf(dev_name, sizeof(dev_name), "cdrom%c", cdrom_drives+'0');
+ cdrom_drives++;
+ } else {
+ snprintf(dev_name, sizeof(dev_name), "sd%c", (hba*7)+id + 'a');
+ }
+
+ if (!(bs_scsi_table[(hba*7)+id] = 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[(hba*7)+id], 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 controller %d, disk %d \n",hba, id);
+ return -1;
+ }
+ if (cdrom_device) {
+ bdrv_set_type_hint(bs_scsi_table[(hba*7)+id], BDRV_TYPE_CDROM);
+ }
+ }
+
+ return 0;
+}
+
+
+
/***********************************************************/
/* USB devices */
@@ -6600,6 +6773,10 @@
"-sd file use 'file' as SecureDigital card image\n"
"-pflash file use 'file' as a parallel flash image\n"
"-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n"
+ "-disk ide,img=file[,hdx=a..d][,type=disk|cdrom] \n"
+ " defaults are: hdx=a,type=disk \n"
+ "-disk scsi,img=file,[hba=n],id=n,type=[disk|cdrom] \n"
+ " defaults are: type=disk,id='auto assign' \n"
"-snapshot write to temporary files instead of disk image files\n"
#ifdef CONFIG_SDL
"-no-frame open SDL window without a frame and window decorations\n"
@@ -6805,6 +6982,7 @@
QEMU_OPTION_semihosting,
QEMU_OPTION_name,
QEMU_OPTION_prom_env,
+ QEMU_OPTION_disk,
};
typedef struct QEMUOption {
@@ -6889,6 +7067,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 },
@@ -7142,7 +7321,12 @@
int i, cdrom_index, pflash_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;
+ int num_ide_cdroms;
const char *pflash_filename[MAX_PFLASH];
const char *sd_filename;
const char *mtd_filename;
@@ -7202,11 +7385,22 @@
register_machines();
machine = first_machine;
cpu_model = NULL;
initrd_filename = NULL;
+ for(i = 0; i < MAX_SCSI_DISKS; i++){
+ scsi_disks_info[i].device_type = SCSI_NONE;
+ bs_scsi_table[i] = NULL;
+ scsi_options[i][0] = NULL;
+ }
+
+ num_ide_disks = 0;
+ num_scsi_disks = 0;
+ num_ide_cdroms = 0;
+ first_bootable_cdrom = 0;
+
for(i = 0; i < MAX_FD; i++)
fd_filename[i] = NULL;
for(i = 0; i < MAX_DISKS; i++)
- hd_filename[i] = NULL;
+ ide_options[i][0] = '\0';
for(i = 0; i < MAX_PFLASH; i++)
pflash_filename[i] = NULL;
pflash_index = 0;
@@ -7254,7 +7446,12 @@
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;
@@ -7324,10 +7525,102 @@
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 ide_disk_index;
+ int scsi_disk_index;
+ int scsi_hba_index;
+
+ fprintf(stdout,"parsing disk option.\n");
+ 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++;
+
+ /* FIXME: take scsi ID into account, specify what controller to use */
+ if (!strcmp(device, "scsi") ){
+ if (num_scsi_disks >= MAX_SCSI_DISKS){
+ fprintf(stderr, "qemu: too many SCSI disks defined.\n");
+ exit(1);
+ }
+ if (get_param_value(device, sizeof(device),"hba",p_input_char)) {
+ if (device[0] >= '0' && device[0] <= ('0'+MAX_SCSI_DISKS)) {
+ scsi_hba_index = device[0] - '0';
+ } else {
+ fprintf(stderr, "qemu: invalid SCSI disk hba= value: %s\n", device);
+ return -1;
+ }
+ }
+ else scsi_hba_index=0;
+ if (get_param_value(device, sizeof(device),"id",p_input_char)) {
+ if (device[0] >= '0' && device[0] <= ('0'+MAX_SCSI_DISKS)) {
+ scsi_disk_index = (7*scsi_hba_index)+(device[0] - '0');
+ } else {
+ fprintf(stderr, "qemu: invalid SCSI disk id= value: %s\n", device);
+ return -1;
+ }
+ }
+ else scsi_disk_index=num_scsi_disks;
+ fprintf(stderr,"DEBUG: adding scsi device %d\n",scsi_disk_index);
+ pstrcpy(scsi_options[scsi_disk_index],
+ 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);
+ }
+ if (get_param_value(device, sizeof(device),"hdx",p_input_char)) {
+ if (device[0] >= 'a' && device[0] <= 'd') {
+ ide_disk_index = device[0] - 'a';
+ } else {
+ fprintf(stderr, "qemu: invalid IDE disk hdx= value: %s\n", device);
+ return -1;
+ }
+ }
+ else ide_disk_index=num_ide_disks;
+ fprintf(stderr,"DEBUG: adding ide disk %d\n",ide_disk_index);
+ pstrcpy(ide_options[ide_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_mtdblock:
@@ -7398,8 +7668,23 @@
kernel_cmdline = optarg;
break;
case QEMU_OPTION_cdrom:
- if (cdrom_index >= 0) {
- hd_filename[cdrom_index] = optarg;
+ {
+ /* FIXME: this is an arbitrary value. what should i be using here? */
+ char buf[200];
+ if (num_ide_disks >= MAX_DISKS){
+ fprintf(stderr, "qemu: too many IDE devices defined.\n");
+ exit(1);
+ }
+ if (num_ide_cdroms >= MAX_IDE_CDROMS){
+ fprintf(stderr, "qemu: too many IDE cdroms defined.\n");
+ exit(1);
+ }
+ snprintf(buf, sizeof(buf), "type=cdrom,hdx=%c,img=%s", num_ide_cdroms + FIRST_IDE_CDROM_DRIVE + 'a',optarg);
+ /* Build new disk IDE syntax string */
+ pstrcpy(ide_options[num_ide_cdroms+FIRST_IDE_CDROM_DRIVE], sizeof(buf), buf);
+ fprintf(stdout,"qemu: ide_options: %s\n",ide_options[num_ide_cdroms+FIRST_IDE_CDROM_DRIVE]);
+ num_ide_cdroms++;
+ num_ide_disks++;
}
break;
case QEMU_OPTION_boot:
@@ -7751,19 +8099,12 @@
linux_boot = (kernel_filename != NULL);
if (!linux_boot &&
boot_device != 'n' &&
- hd_filename[0] == '\0' &&
- (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
+ num_ide_disks == 0 &&
+ num_scsi_disks == 0 &&
fd_filename[0] == '\0')
help(1);
- /* boot to floppy or the default cd if no hard disk defined yet */
- if (hd_filename[0] == '\0' && boot_device == 'c') {
- if (fd_filename[0] != '\0')
- boot_device = 'a';
- else
- boot_device = 'd';
- }
setvbuf(stdout, NULL, _IOLBF, 0);
@@ -7833,31 +8109,21 @@
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,
+ cyls, heads, secs, translation)){
+ exit(1);
+ }
+
+ /* boot to floppy or default cd if no hard disk */
+ if (num_ide_disks == 0 && num_scsi_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 */
--- vl.h.orig 2006-10-09 10:30:32.000000000 -0400
+++ vl.h 2006-12-04 10:38:01.000000000 -0500
@@ -1396,10 +1396,38 @@
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 hba;
+ int id;
+ scsi_devices device_type;
+ } SCSIDiskInfo;
+
+#define MAX_SCSI_CONTROLLERS 4
+#define MAX_SCSI_DISKS 7*MAX_SCSI_CONTROLLERS
+/* cdroms start at C, end at D. primary controller dosent support cdrom drives? */
+#define FIRST_IDE_CDROM_DRIVE 2
+#define MAX_IDE_CDROMS 2
+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 lsi adapters */
+extern int scsi_disks; /* Count of scsi disks/cdroms */
+extern int cdrom_drives; /* Count of total cdroms */
/* integratorcp.c */
extern QEMUMachine integratorcp_machine;
next reply other threads:[~2007-07-24 21:31 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-07-24 21:30 risc [this message]
-- strict thread matches above, loose matches on Subject: below --
2007-07-24 21:24 [Qemu-devel] -disk patch risc
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070724213001.GT4797@volumehost.com \
--to=risc@volumehost.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.