From: Jeff Garzik <jgarzik@pobox.com>
To: alan@lxorguk.ukuu.org.uk
Cc: akpm@osdl.org, linux-ide@vger.kernel.org,
root <root@hraefn.swansea.linux.org.uk>,
Alan Cox <alan@redhat.com>
Subject: Re: [PATCH 07/24] libata: Fix the host_set hacks and sort out simplex mode
Date: Fri, 07 Jul 2006 12:15:53 -0400 [thread overview]
Message-ID: <44AE88B9.2080800@pobox.com> (raw)
In-Reply-To: <1152036113264-git-send-email-alan@lxorguk.ukuu.org.uk>
alan@lxorguk.ukuu.org.uk wrote:
> From: root <root@hraefn.swansea.linux.org.uk>
>
> A host_set and probe_ent now have an "irq2" field which is used for the
> legacy interface cases. Currently we still check both ports on either IRQ
> but a little thinking suggests this is only a minor performance glitch that
> can be fixed later on.
>
> Also sorted out the FIXME for making port addresses for legacy ports adjustable
> by platform. This may not be enough for PA-RISC and other platforms with PCI
> bridges hung off a different primary bridge. We'll cross that bridge ;) when
> we come to it.
>
> Alan
>
> Signed-off-by: Alan Cox <alan@redhat.com>
I am thinking about touching this area heavily, for iomap support, in
the next couple days. iomap support requires making irq/IO/MMIO
resource handling more sane, and so should be a better patch than this
(and heavily touches the same areas).
FWIW, iomap means that, like MMIO (ioremap), you must map IO ports
obtained from pci_resource_start().
If nothing happens in a few days, please yell at me, and I'll apply this
patch and work on top of it. As it stands, it does some things I don't
want (irq2) and wish to avoid.
Some minor inline comments below, as well...
> drivers/scsi/libata-bmdma.c | 134 ++++++++++++++++-------------------
> drivers/scsi/libata-core.c | 40 ++++++++--
> include/asm-alpha/libata-portmap.h | 12 +++
> include/asm-i386/libata-portmap.h | 12 +++
> include/asm-x86_64/libata-portmap.h | 12 +++
> include/linux/libata.h | 5 +
> 6 files changed, 135 insertions(+), 80 deletions(-)
> create mode 100644 include/asm-alpha/libata-portmap.h
> create mode 100644 include/asm-i386/libata-portmap.h
> create mode 100644 include/asm-x86_64/libata-portmap.h
>
> 1addd5a92018c7ed53756bf84854e1b6b45c2d12
> diff --git a/drivers/scsi/libata-bmdma.c b/drivers/scsi/libata-bmdma.c
> index 004e1a0..b1dfa8c 100644
> --- a/drivers/scsi/libata-bmdma.c
> +++ b/drivers/scsi/libata-bmdma.c
> @@ -881,7 +881,7 @@ ata_pci_init_native_mode(struct pci_dev
> if (bmdma) {
> bmdma += 8;
> if(inb(bmdma + 2) & 0x80)
> - probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
> + probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
> probe_ent->port[p].bmdma_addr = bmdma;
> }
> ata_std_ports(&probe_ent->port[p]);
> @@ -894,45 +894,55 @@ ata_pci_init_native_mode(struct pci_dev
>
>
> static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
> - struct ata_port_info *port, int port_num)
> + struct ata_port_info **port, int port_mask)
> {
> struct ata_probe_ent *probe_ent;
> - unsigned long bmdma;
> + unsigned long bmdma = pci_resource_start(pdev, 4);
> +
> + int port_num = 0;
>
> - probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port);
> + probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
> if (!probe_ent)
> return NULL;
>
> probe_ent->legacy_mode = 1;
> probe_ent->n_ports = 1;
> - probe_ent->hard_port_no = port_num;
> - probe_ent->private_data = port->private_data;
> + probe_ent->hard_port_no = 0;
> + probe_ent->private_data = port[0]->private_data;
>
> - switch(port_num)
> - {
> - case 0:
> - probe_ent->irq = 14;
> - probe_ent->port[0].cmd_addr = 0x1f0;
> - probe_ent->port[0].altstatus_addr =
> - probe_ent->port[0].ctl_addr = 0x3f6;
> - break;
> - case 1:
> - probe_ent->irq = 15;
> - probe_ent->port[0].cmd_addr = 0x170;
> - probe_ent->port[0].altstatus_addr =
> - probe_ent->port[0].ctl_addr = 0x376;
> - break;
> + if (port_mask & ATA_PORT_PRIMARY) {
> + probe_ent->irq = 14;
> + probe_ent->port[port_num].cmd_addr = ATA_PRIMARY_CMD;
> + probe_ent->port[port_num].altstatus_addr =
> + probe_ent->port[port_num].ctl_addr = ATA_PRIMARY_CTL;
> + if (bmdma) {
> + probe_ent->port[0].bmdma_addr = bmdma;
> + if (inb(bmdma + 2) & 0x80)
> + probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
> + }
> + ata_std_ports(&probe_ent->port[port_num]);
> + port_num ++;
> }
> -
> - bmdma = pci_resource_start(pdev, 4);
> - if (bmdma != 0) {
> - bmdma += 8 * port_num;
> - probe_ent->port[0].bmdma_addr = bmdma;
> - if (inb(bmdma + 2) & 0x80)
> - probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
> + if (port_mask & ATA_PORT_SECONDARY) {
> + if (port_num == 1)
> + probe_ent->irq2 = 15;
> + else {
> + /* Secondary only. IRQ 15 only and "first" port is port 1 */
> + probe_ent->irq = 15;
> + probe_ent->hard_port_no = 1;
> + }
> + probe_ent->port[port_num].cmd_addr = ATA_SECONDARY_CMD;
> + probe_ent->port[port_num].altstatus_addr =
> + probe_ent->port[port_num].ctl_addr = ATA_SECONDARY_CTL;
> + port_num ++;
> + if (bmdma) {
> + probe_ent->port[port_num].bmdma_addr = bmdma + 8;
> + if (inb(bmdma + 10) & 0x80)
> + probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
> + }
> + ata_std_ports(&probe_ent->port[port_num]);
> + port_num ++;
> }
> - ata_std_ports(&probe_ent->port[0]);
> -
this looks like a needed improvement
> @@ -951,6 +961,10 @@ static struct ata_probe_ent *ata_pci_ini
> * regions, sets the dma mask, enables bus master mode, and calls
> * ata_device_add()
> *
> + * ASSUMPTION:
> + * Nobody makes a single channel controller that appears solely as
> + * the secondary legacy port on PCI.
> + *
> * LOCKING:
> * Inherited from PCI layer (may sleep).
> *
> @@ -961,7 +975,7 @@ static struct ata_probe_ent *ata_pci_ini
> int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
> unsigned int n_ports)
> {
> - struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL;
> + struct ata_probe_ent *probe_ent = NULL;
> struct ata_port_info *port[2];
> u8 tmp8, mask;
> unsigned int legacy_mode = 0;
> @@ -1010,35 +1024,34 @@ int ata_pci_init_one (struct pci_dev *pd
> goto err_out;
> }
>
> - /* FIXME: Should use platform specific mappers for legacy port ranges */
> if (legacy_mode) {
> - if (!request_region(0x1f0, 8, "libata")) {
> + if (!request_region(ATA_PRIMARY_CMD, 8, "libata")) {
> struct resource *conflict, res;
> - res.start = 0x1f0;
> - res.end = 0x1f0 + 8 - 1;
> + res.start = ATA_PRIMARY_CMD;
> + res.end = ATA_PRIMARY_CMD + 8 - 1;
> conflict = ____request_resource(&ioport_resource, &res);
> if (!strcmp(conflict->name, "libata"))
> - legacy_mode |= (1 << 0);
> + legacy_mode |= ATA_PORT_PRIMARY;
> else {
> disable_dev_on_err = 0;
> - printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n");
> + printk(KERN_WARNING "ata: 0x%0X IDE port busy\n", ATA_PRIMARY_CMD);
> }
> } else
> - legacy_mode |= (1 << 0);
> + legacy_mode |= ATA_PORT_PRIMARY;
>
> - if (!request_region(0x170, 8, "libata")) {
> + if (!request_region(ATA_SECONDARY_CMD, 8, "libata")) {
> struct resource *conflict, res;
> - res.start = 0x170;
> - res.end = 0x170 + 8 - 1;
> + res.start = ATA_SECONDARY_CMD;
> + res.end = ATA_SECONDARY_CMD + 8 - 1;
> conflict = ____request_resource(&ioport_resource, &res);
> if (!strcmp(conflict->name, "libata"))
> - legacy_mode |= (1 << 1);
> + legacy_mode |= ATA_PORT_SECONDARY;
> else {
> disable_dev_on_err = 0;
> - printk(KERN_WARNING "ata: 0x170 IDE port busy\n");
> + printk(KERN_WARNING "ata: 0x%X IDE port busy\n", ATA_SECONDARY_CMD);
> }
> } else
> - legacy_mode |= (1 << 1);
> + legacy_mode |= ATA_PORT_SECONDARY;
> }
>
> /* we have legacy mode, but all ports are unavailable */
> @@ -1056,17 +1069,14 @@ int ata_pci_init_one (struct pci_dev *pd
> goto err_out_regions;
>
> if (legacy_mode) {
> - if (legacy_mode & (1 << 0))
> - probe_ent = ata_pci_init_legacy_port(pdev, port[0], 0);
> - if (legacy_mode & (1 << 1))
> - probe_ent2 = ata_pci_init_legacy_port(pdev, port[1], 1);
> + probe_ent = ata_pci_init_legacy_port(pdev, port, legacy_mode);
> } else {
> if (n_ports == 2)
> probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
> else
> probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY);
> }
> - if (!probe_ent && !probe_ent2) {
> + if (!probe_ent) {
> rc = -ENOMEM;
> goto err_out_regions;
> }
ditto, some nice cleanups of ugly (but necessary) code
> @@ -1074,35 +1084,17 @@ int ata_pci_init_one (struct pci_dev *pd
> pci_set_master(pdev);
>
> /* FIXME: check ata_device_add return */
> - if (legacy_mode) {
> - struct device *dev = &pdev->dev;
> - struct ata_host_set *host_set = NULL;
> -
> - if (legacy_mode & (1 << 0)) {
> - ata_device_add(probe_ent);
> - host_set = dev_get_drvdata(dev);
> - }
> -
> - if (legacy_mode & (1 << 1)) {
> - ata_device_add(probe_ent2);
> - if (host_set) {
> - host_set->next = dev_get_drvdata(dev);
> - dev_set_drvdata(dev, host_set);
> - }
> - }
> - } else
> - ata_device_add(probe_ent);
> + ata_device_add(probe_ent);
>
> kfree(probe_ent);
> - kfree(probe_ent2);
>
> return 0;
>
> err_out_regions:
> - if (legacy_mode & (1 << 0))
> - release_region(0x1f0, 8);
> - if (legacy_mode & (1 << 1))
> - release_region(0x170, 8);
> + if (legacy_mode & ATA_PORT_PRIMARY)
> + release_region(ATA_PRIMARY_CMD, 8);
> + if (legacy_mode & ATA_PORT_SECONDARY)
> + release_region(ATA_SECONDARY_CMD, 8);
> pci_release_regions(pdev);
ditto
> diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
> index d1c1c30..cc6ae67 100644
> --- a/drivers/scsi/libata-core.c
> +++ b/drivers/scsi/libata-core.c
> @@ -5232,6 +5232,7 @@ static void ata_host_init(struct ata_por
> ap->host_set = host_set;
> ap->dev = ent->dev;
> ap->port_no = port_no;
> +
> ap->hard_port_no =
> ent->legacy_mode ? ent->hard_port_no : port_no;
> ap->pio_mask = ent->pio_mask;
> @@ -5367,6 +5368,7 @@ int ata_device_add(const struct ata_prob
> host_set->dev = dev;
> host_set->n_ports = ent->n_ports;
> host_set->irq = ent->irq;
> + host_set->irq2 = ent->irq2;
> host_set->mmio_base = ent->mmio_base;
> host_set->private_data = ent->private_data;
> host_set->ops = ent->port_ops;
> @@ -5376,16 +5378,23 @@ int ata_device_add(const struct ata_prob
> for (i = 0; i < ent->n_ports; i++) {
> struct ata_port *ap;
> unsigned long xfer_mode_mask;
> + int irq_line = ent->irq;
> +
>
> ap = ata_host_add(ent, host_set, i);
> if (!ap)
> goto err_out;
>
> + /* Report the secondary IRQ for second channel legacy */
> + if (i == 1 && ent->irq2)
> + irq_line = ent->irq2;
> +
> host_set->ports[i] = ap;
> xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) |
> (ap->mwdma_mask << ATA_SHIFT_MWDMA) |
> (ap->pio_mask << ATA_SHIFT_PIO);
>
> + /* FIXME: maybe print both IRQ lines ? */
> /* print per-port info to dmesg */
> ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%lX "
> "ctl 0x%lX bmdma 0x%lX irq %lu\n",
> @@ -5405,7 +5414,7 @@ int ata_device_add(const struct ata_prob
> if (!count)
> goto err_free_ret;
>
> - /* obtain irq, that is shared between channels */
> + /* obtain irq, that may be shared between channels */
> rc = request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,
> DRV_NAME, host_set);
> if (rc) {
> @@ -5414,6 +5423,21 @@ int ata_device_add(const struct ata_prob
> goto err_out;
> }
>
> + /* do we have a second IRQ for the other channel, eg legacy mode */
> + if (ent->irq2) {
> + /* We will get weird core code crashes later if this is true
> + so trap it now */
> + BUG_ON(ent->irq == ent->irq2);
> +
> + rc = request_irq(ent->irq2, ent->port_ops->irq_handler, ent->irq_flags,
> + DRV_NAME, host_set);
> + if (rc) {
> + dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n",
> + ent->irq2, rc);
> + goto err_out;
> + }
> + }
> +
> /* perform each probe synchronously */
> DPRINTK("probe begin\n");
> for (i = 0; i < count; i++) {
As you know, this is the nasty part that I _really_ want to avoid.
This is compounding my design mistake of putting request_irq() in the
core code.
Such code is appropriate ONLY in libata-bmdma.c (PCI IDE-specific code).
> @@ -5574,6 +5598,8 @@ void ata_host_set_remove(struct ata_host
> ata_port_detach(host_set->ports[i]);
>
> free_irq(host_set->irq, host_set);
> + if (host_set->irq2)
> + free_irq(host_set->irq2, host_set);
>
> for (i = 0; i < host_set->n_ports; i++) {
> struct ata_port *ap = host_set->ports[i];
> @@ -5583,10 +5609,11 @@ void ata_host_set_remove(struct ata_host
> if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {
> struct ata_ioports *ioaddr = &ap->ioaddr;
>
> - if (ioaddr->cmd_addr == 0x1f0)
> - release_region(0x1f0, 8);
> - else if (ioaddr->cmd_addr == 0x170)
> - release_region(0x170, 8);
> + /* FIXME: Add -ac IDE pci mods to remove these special cases */
> + if (ioaddr->cmd_addr == ATA_PRIMARY_CMD)
> + release_region(ATA_PRIMARY_CMD, 8);
> + else if (ioaddr->cmd_addr == ATA_SECONDARY_CMD)
> + release_region(ATA_SECONDARY_CMD, 8);
> }
>
> scsi_host_put(ap->host);
FWIW, this is also the area where ioport_unmap() calls will go.
> @@ -5679,11 +5706,8 @@ void ata_pci_remove_one (struct pci_dev
> {
> struct device *dev = pci_dev_to_dev(pdev);
> struct ata_host_set *host_set = dev_get_drvdata(dev);
> - struct ata_host_set *host_set2 = host_set->next;
>
> ata_host_set_remove(host_set);
> - if (host_set2)
> - ata_host_set_remove(host_set2);
>
> pci_release_regions(pdev);
> pci_disable_device(pdev);
Though it is very nice to remove host_set->next.
> diff --git a/include/asm-alpha/libata-portmap.h b/include/asm-alpha/libata-portmap.h
> new file mode 100644
> index 0000000..9202fd0
> --- /dev/null
> +++ b/include/asm-alpha/libata-portmap.h
> @@ -0,0 +1,12 @@
> +#ifndef __ASM_GENERIC_LIBATA_PORTMAP_H
> +#define __ASM_GENERIC_LIBATA_PORTMAP_H
> +
> +#define ATA_PRIMARY_CMD 0x1F0
> +#define ATA_PRIMARY_CTL 0x3F6
> +#define ATA_PRIMARY_IRQ 14
> +
> +#define ATA_SECONDARY_CMD 0x170
> +#define ATA_SECONDARY_CTL 0x376
> +#define ATA_SECONDARY_IRQ 15
> +
> +#endif
> diff --git a/include/asm-i386/libata-portmap.h b/include/asm-i386/libata-portmap.h
> new file mode 100644
> index 0000000..9202fd0
> --- /dev/null
> +++ b/include/asm-i386/libata-portmap.h
> @@ -0,0 +1,12 @@
> +#ifndef __ASM_GENERIC_LIBATA_PORTMAP_H
> +#define __ASM_GENERIC_LIBATA_PORTMAP_H
> +
> +#define ATA_PRIMARY_CMD 0x1F0
> +#define ATA_PRIMARY_CTL 0x3F6
> +#define ATA_PRIMARY_IRQ 14
> +
> +#define ATA_SECONDARY_CMD 0x170
> +#define ATA_SECONDARY_CTL 0x376
> +#define ATA_SECONDARY_IRQ 15
> +
> +#endif
> diff --git a/include/asm-x86_64/libata-portmap.h b/include/asm-x86_64/libata-portmap.h
> new file mode 100644
> index 0000000..9202fd0
> --- /dev/null
> +++ b/include/asm-x86_64/libata-portmap.h
> @@ -0,0 +1,12 @@
> +#ifndef __ASM_GENERIC_LIBATA_PORTMAP_H
> +#define __ASM_GENERIC_LIBATA_PORTMAP_H
> +
> +#define ATA_PRIMARY_CMD 0x1F0
> +#define ATA_PRIMARY_CTL 0x3F6
> +#define ATA_PRIMARY_IRQ 14
> +
> +#define ATA_SECONDARY_CMD 0x170
> +#define ATA_SECONDARY_CTL 0x376
> +#define ATA_SECONDARY_IRQ 15
> +
> +#endif
This is either silly, or obviously-preliminary code.
We don't want to duplicate this information, but instead do as your
__ASM_GENERIC_LIBATA_PORTMAP_H symbol implies: put a single copy into
include/asm-generic.
next prev parent reply other threads:[~2006-07-07 16:15 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-07-04 18:14 PATA updates (rebased) alan
2006-07-04 18:14 ` [PATCH 01/24] ata_piix TIME0/TIME1 setup alan
2006-07-04 18:14 ` [PATCH 02/24] pata_ali - further debug work alan
2006-07-04 18:15 ` [PATCH 03/24] pata_amd - new chips alan
2006-07-04 18:17 ` [PATCH 04/24] pata_pcmcia: Make drivers/scsi/pata_pcmcia.c:pcmcia_remove_one() static alan
2006-07-04 18:14 ` [PATCH 05/24] pata_ali: Revisions below 0x20 need CD config poking too alan
2006-07-04 18:14 ` [PATCH 06/24] Sort out MC65 compile for now alan
2006-07-04 18:15 ` [PATCH 07/24] libata: Fix the host_set hacks and sort out simplex mode alan
2006-07-04 18:15 ` [PATCH 08/24] pata_it821x: Fix pass through alan
2006-07-04 18:14 ` [PATCH 09/24] pci_ids: Add JMicron identifiers as we need them in various drivers and quirks alan
2006-07-04 18:14 ` [PATCH 10/24] ahci: Ensure that we don't grab both functions alan
2006-07-04 18:14 ` [PATCH 11/24] jmicron: Add quirks to force the device into a sane mode alan
2006-07-04 18:14 ` [PATCH 12/24] jmicron: Configuration alan
2006-07-04 18:14 ` [PATCH 13/24] My name is Ingo Molnar, you killed my make allyesconfig, prepare to die alan
2006-07-04 18:15 ` [PATCH 14/24] it821x: Fix the ATAPI autodma setup alan
2006-07-04 18:14 ` [PATCH 15/24] ata_generic - generic BIOS setup SFF ATA driver alan
2006-07-04 18:15 ` [PATCH 16/24] jmicron: IDE old type driver alan
2006-07-04 18:15 ` [PATCH 17/24] pata_qdi: Fix return code alan
2006-07-04 18:15 ` [PATCH 18/24] ide jmicron: Finish writing alan
2006-07-04 18:15 ` [PATCH 19/24] jmicron: It works better if you get the file name right alan
2006-07-04 18:15 ` [PATCH 20/24] jmicron: Further clean up alan
2006-07-04 18:15 ` [PATCH 21/24] ata_jmicro: Fix an escapee alan
2006-07-04 18:14 ` [PATCH 22/24] jmicron: Jmicron multifunction setup alan
2006-07-04 18:15 ` [PATCH 23/24] libata: Enable per device speed setting alan
2006-07-04 18:15 ` [PATCH 24/24] jmicron: Missed one alan
2006-07-07 16:36 ` Jeff Garzik
2006-07-07 16:39 ` [PATCH 23/24] libata: Enable per device speed setting Jeff Garzik
2006-07-07 17:06 ` Alan Cox
2006-07-07 16:34 ` [PATCH 22/24] jmicron: Jmicron multifunction setup Jeff Garzik
[not found] ` <20060707124359.670e84c6.akpm@osdl.o! rg>
2006-07-07 19:43 ` Andrew Morton
2006-07-07 19:48 ` Jeff Garzik
2006-07-07 20:01 ` Andrew Morton
2006-07-07 20:05 ` Jeff Garzik
2006-07-07 19:45 ` Andrew Morton
2006-07-07 19:50 ` Jeff Garzik
2006-07-07 16:35 ` Jeff Garzik
2006-07-07 16:31 ` [PATCH 17/24] pata_qdi: Fix return code Jeff Garzik
2006-07-07 16:31 ` [PATCH 15/24] ata_generic - generic BIOS setup SFF ATA driver Jeff Garzik
2006-07-07 17:20 ` Alan Cox
2006-07-07 17:22 ` Jeff Garzik
2006-07-07 16:26 ` [PATCH 14/24] it821x: Fix the ATAPI autodma setup Jeff Garzik
2006-07-07 16:25 ` [PATCH 13/24] My name is Ingo Molnar, you killed my make allyesconfig, prepare to die Jeff Garzik
2006-07-07 16:23 ` [PATCH 11/24] jmicron: Add quirks to force the device into a sane mode Jeff Garzik
2006-07-07 16:51 ` Alan Cox
2006-07-07 16:15 ` Jeff Garzik [this message]
2006-07-07 16:50 ` [PATCH 07/24] libata: Fix the host_set hacks and sort out simplex mode Alan Cox
2006-07-05 12:44 ` PATA updates (rebased) Erik Mouw
2006-07-05 16:15 ` Alan Cox
2006-07-07 16:07 ` Jeff Garzik
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=44AE88B9.2080800@pobox.com \
--to=jgarzik@pobox.com \
--cc=akpm@osdl.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=alan@redhat.com \
--cc=linux-ide@vger.kernel.org \
--cc=root@hraefn.swansea.linux.org.uk \
/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.