All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
To: linux-ide@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] ide: use lock bitops for ports serialization (v2)
Date: Sun, 21 Dec 2008 21:56:07 +0100	[thread overview]
Message-ID: <200812212156.08723.bzolnier@gmail.com> (raw)


during more testing it turned out that v1 was too optimistic w.r.t.
devices serialization, v2 fixes it (so the patch can be finally merged
into pata-2.6 tree)

From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Subject: [PATCH] ide: use lock bitops for ports serialization (v2)

* Add ->host_busy field to struct ide_host and use it's first bit
  together with lock bitops to provide new ports serialization method.

* Convert core IDE code to use new ide_[un]lock_host() helpers.

  This removes the need for taking hwgroup->lock if host is already
  busy on serialized hosts and makes it possible to merge ide_hwgroup_t
  into ide_hwif_t (done in the later patch).

* Remove no longer needed ide_hwgroup_t.busy and ide_[un]lock_hwgroup().

* Update do_ide_request() documentation.

v2:
* ide_release_lock() should be called inside IDE_HFLAG_SERIALIZE check.

* Add ide_hwif_t.busy flag and ide_[un]lock_port() for serializing
  devices on a port.

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/ide/ide-io.c |  105 ++++++++++++++++++++++++++++++---------------------
 include/linux/ide.h  |   35 ++---------------
 2 files changed, 69 insertions(+), 71 deletions(-)

Index: b/drivers/ide/ide-io.c
===================================================================
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -666,45 +666,54 @@ void ide_stall_queue (ide_drive_t *drive
 }
 EXPORT_SYMBOL(ide_stall_queue);
 
+static inline int ide_lock_port(ide_hwif_t *hwif)
+{
+	if (hwif->busy)
+		return 1;
+
+	hwif->busy = 1;
+
+	return 0;
+}
+
+static inline void ide_unlock_port(ide_hwif_t *hwif)
+{
+	hwif->busy = 0;
+}
+
+static inline int ide_lock_host(struct ide_host *host, ide_hwif_t *hwif)
+{
+	int rc = 0;
+
+	if (host->host_flags & IDE_HFLAG_SERIALIZE) {
+		rc = test_and_set_bit_lock(IDE_HOST_BUSY, &host->host_busy);
+		if (rc == 0) {
+			/* for atari only */
+			ide_get_lock(ide_intr, hwif);
+		}
+	}
+	return rc;
+}
+
+static inline void ide_unlock_host(struct ide_host *host)
+{
+	if (host->host_flags & IDE_HFLAG_SERIALIZE) {
+		/* for atari only */
+		ide_release_lock();
+		clear_bit_unlock(IDE_HOST_BUSY, &host->host_busy);
+	}
+}
+
 /*
  * Issue a new request to a drive from hwgroup
- *
- * A hwgroup is a serialized group of IDE interfaces.  Usually there is
- * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640)
- * may have both interfaces in a single hwgroup to "serialize" access.
- * Or possibly multiple ISA interfaces can share a common IRQ by being grouped
- * together into one hwgroup for serialized access.
- *
- * Note also that several hwgroups can end up sharing a single IRQ,
- * possibly along with many other devices.  This is especially common in
- * PCI-based systems with off-board IDE controller cards.
- *
- * The IDE driver uses a per-hwgroup lock to protect the hwgroup->busy flag.
- *
- * The first thread into the driver for a particular hwgroup sets the
- * hwgroup->busy flag to indicate that this hwgroup is now active,
- * and then initiates processing of the top request from the request queue.
- *
- * Other threads attempting entry notice the busy setting, and will simply
- * queue their new requests and exit immediately.  Note that hwgroup->busy
- * remains set even when the driver is merely awaiting the next interrupt.
- * Thus, the meaning is "this hwgroup is busy processing a request".
- *
- * When processing of a request completes, the completing thread or IRQ-handler
- * will start the next request from the queue.  If no more work remains,
- * the driver will clear the hwgroup->busy flag and exit.
- *
- * The per-hwgroup spinlock is used to protect all access to the
- * hwgroup->busy flag, but is otherwise not needed for most processing in
- * the driver.  This makes the driver much more friendlier to shared IRQs
- * than previous designs, while remaining 100% (?) SMP safe and capable.
  */
 void do_ide_request(struct request_queue *q)
 {
 	ide_drive_t	*drive = q->queuedata;
 	ide_hwif_t	*hwif = drive->hwif;
+	struct ide_host *host = hwif->host;
 	ide_hwgroup_t	*hwgroup = hwif->hwgroup;
-	struct request	*rq;
+	struct request	*rq = NULL;
 	ide_startstop_t	startstop;
 
 	/*
@@ -721,9 +730,13 @@ void do_ide_request(struct request_queue
 		blk_remove_plug(q);
 
 	spin_unlock_irq(q->queue_lock);
+
+	if (ide_lock_host(host, hwif))
+		goto plug_device_2;
+
 	spin_lock_irq(&hwgroup->lock);
 
-	if (!ide_lock_hwgroup(hwgroup, hwif)) {
+	if (!ide_lock_port(hwif)) {
 		ide_hwif_t *prev_port;
 repeat:
 		prev_port = hwif->host->cur_port;
@@ -731,7 +744,7 @@ repeat:
 
 		if (drive->dev_flags & IDE_DFLAG_SLEEPING) {
 			if (time_before(drive->sleep, jiffies)) {
-				ide_unlock_hwgroup(hwgroup);
+				ide_unlock_port(hwif);
 				goto plug_device;
 			}
 		}
@@ -761,7 +774,7 @@ repeat:
 		spin_lock_irq(&hwgroup->lock);
 
 		if (!rq) {
-			ide_unlock_hwgroup(hwgroup);
+			ide_unlock_port(hwif);
 			goto out;
 		}
 
@@ -782,7 +795,7 @@ repeat:
 		    blk_pm_request(rq) == 0 &&
 		    (rq->cmd_flags & REQ_PREEMPT) == 0) {
 			/* there should be no pending command at this point */
-			ide_unlock_hwgroup(hwgroup);
+			ide_unlock_port(hwif);
 			goto plug_device;
 		}
 
@@ -798,11 +811,15 @@ repeat:
 		goto plug_device;
 out:
 	spin_unlock_irq(&hwgroup->lock);
+	if (rq == NULL)
+		ide_unlock_host(host);
 	spin_lock_irq(q->queue_lock);
 	return;
 
 plug_device:
 	spin_unlock_irq(&hwgroup->lock);
+	ide_unlock_host(host);
+plug_device_2:
 	spin_lock_irq(q->queue_lock);
 
 	if (!elv_queue_empty(q))
@@ -844,9 +861,9 @@ static ide_startstop_t ide_dma_timeout_r
 	ide_dma_off_quietly(drive);
 
 	/*
-	 * un-busy drive etc (hwgroup->busy is cleared on return) and
-	 * make sure request is sane
+	 * un-busy drive etc and make sure request is sane
 	 */
+
 	rq = HWGROUP(drive)->rq;
 
 	if (!rq)
@@ -895,6 +912,7 @@ static void ide_plug_device(ide_drive_t 
 void ide_timer_expiry (unsigned long data)
 {
 	ide_hwgroup_t	*hwgroup = (ide_hwgroup_t *) data;
+	ide_hwif_t	*uninitialized_var(hwif);
 	ide_drive_t	*uninitialized_var(drive);
 	ide_handler_t	*handler;
 	ide_expiry_t	*expiry;
@@ -918,7 +936,6 @@ void ide_timer_expiry (unsigned long dat
 			printk(KERN_ERR "%s: ->cur_dev was NULL\n", __func__);
 			hwgroup->handler = NULL;
 		} else {
-			ide_hwif_t *hwif;
 			ide_startstop_t startstop = ide_stopped;
 
 			if ((expiry = hwgroup->expiry) != NULL) {
@@ -964,15 +981,17 @@ void ide_timer_expiry (unsigned long dat
 			spin_lock_irq(&hwgroup->lock);
 			enable_irq(hwif->irq);
 			if (startstop == ide_stopped) {
-				ide_unlock_hwgroup(hwgroup);
+				ide_unlock_port(hwif);
 				plug_device = 1;
 			}
 		}
 	}
 	spin_unlock_irqrestore(&hwgroup->lock, flags);
 
-	if (plug_device)
+	if (plug_device) {
+		ide_unlock_host(hwif->host);
 		ide_plug_device(drive);
+	}
 }
 
 /**
@@ -1150,7 +1169,7 @@ irqreturn_t ide_intr (int irq, void *dev
 	 */
 	if (startstop == ide_stopped) {
 		if (hwgroup->handler == NULL) {	/* paranoia */
-			ide_unlock_hwgroup(hwgroup);
+			ide_unlock_port(hwif);
 			plug_device = 1;
 		} else
 			printk(KERN_ERR "%s: %s: huh? expected NULL handler "
@@ -1161,8 +1180,10 @@ out_handled:
 out:
 	spin_unlock_irqrestore(&hwgroup->lock, flags);
 out_early:
-	if (plug_device)
+	if (plug_device) {
+		ide_unlock_host(hwif->host);
 		ide_plug_device(drive);
+	}
 
 	return irq_ret;
 }
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -828,6 +828,7 @@ typedef struct hwif_s {
 
 	unsigned	present    : 1;	/* this interface exists */
 	unsigned	sg_mapped  : 1;	/* sg_table and sg_nents are ready */
+	unsigned	busy	   : 1; /* serializes devices on a port */
 
 	struct device		gendev;
 	struct device		*portdev;
@@ -851,8 +852,13 @@ struct ide_host {
 	unsigned long	host_flags;
 	void		*host_priv;
 	ide_hwif_t	*cur_port;	/* for hosts requiring serialization */
+
+	/* used for hosts requiring serialization */
+	volatile long	host_busy;
 };
 
+#define IDE_HOST_BUSY 0
+
 /*
  *  internal ide interrupt handler type
  */
@@ -866,8 +872,6 @@ typedef struct hwgroup_s {
 		/* irq handler, if active */
 	ide_startstop_t	(*handler)(ide_drive_t *);
 
-		/* BOOL: protects all fields below */
-	volatile int busy;
 		/* BOOL: polling active & poll_timeout field valid */
 	unsigned int polling	: 1;
 
@@ -1271,26 +1275,6 @@ extern void ide_stall_queue(ide_drive_t 
 
 extern void ide_timer_expiry(unsigned long);
 extern irqreturn_t ide_intr(int irq, void *dev_id);
-
-static inline int ide_lock_hwgroup(ide_hwgroup_t *hwgroup, ide_hwif_t *hwif)
-{
-	if (hwgroup->busy)
-		return 1;
-
-	hwgroup->busy = 1;
-	/* for atari only */
-	ide_get_lock(ide_intr, hwif);
-
-	return 0;
-}
-
-static inline void ide_unlock_hwgroup(ide_hwgroup_t *hwgroup)
-{
-	/* for atari only */
-	ide_release_lock();
-	hwgroup->busy = 0;
-}
-
 extern void do_ide_request(struct request_queue *);
 
 void ide_init_disk(struct gendisk *, ide_drive_t *);
@@ -1617,13 +1601,6 @@ static inline void ide_set_max_pio(ide_d
 
 extern spinlock_t ide_lock;
 extern struct mutex ide_cfg_mtx;
-/*
- * Structure locking:
- *
- * ide_hwgroup_t->busy: hwgroup->lock
- * ide_hwif_t->{hwgroup,mate}: constant, no locking
- * ide_drive_t->hwif: constant, no locking
- */
 
 #define local_irq_set(flags)	do { local_save_flags((flags)); local_irq_enable_in_hardirq(); } while (0)
 
\0

WARNING: multiple messages have this Message-ID (diff)
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
To: linux-ide@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] ide: use lock bitops for ports serialization (v2)
Date: Sun, 21 Dec 2008 21:56:07 +0100	[thread overview]
Message-ID: <200812212156.08723.bzolnier@gmail.com> (raw)


during more testing it turned out that v1 was too optimistic w.r.t.devices serialization, v2 fixes it (so the patch can be finally mergedinto pata-2.6 tree)
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>Subject: [PATCH] ide: use lock bitops for ports serialization (v2)
* Add ->host_busy field to struct ide_host and use it's first bit  together with lock bitops to provide new ports serialization method.
* Convert core IDE code to use new ide_[un]lock_host() helpers.
  This removes the need for taking hwgroup->lock if host is already  busy on serialized hosts and makes it possible to merge ide_hwgroup_t  into ide_hwif_t (done in the later patch).
* Remove no longer needed ide_hwgroup_t.busy and ide_[un]lock_hwgroup().
* Update do_ide_request() documentation.
v2:* ide_release_lock() should be called inside IDE_HFLAG_SERIALIZE check.
* Add ide_hwif_t.busy flag and ide_[un]lock_port() for serializing  devices on a port.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>--- drivers/ide/ide-io.c |  105 ++++++++++++++++++++++++++++++--------------------- include/linux/ide.h  |   35 ++--------------- 2 files changed, 69 insertions(+), 71 deletions(-)
Index: b/drivers/ide/ide-io.c===================================================================--- a/drivers/ide/ide-io.c+++ b/drivers/ide/ide-io.c@@ -666,45 +666,54 @@ void ide_stall_queue (ide_drive_t *drive } EXPORT_SYMBOL(ide_stall_queue); +static inline int ide_lock_port(ide_hwif_t *hwif)+{+	if (hwif->busy)+		return 1;++	hwif->busy = 1;++	return 0;+}++static inline void ide_unlock_port(ide_hwif_t *hwif)+{+	hwif->busy = 0;+}++static inline int ide_lock_host(struct ide_host *host, ide_hwif_t *hwif)+{+	int rc = 0;++	if (host->host_flags & IDE_HFLAG_SERIALIZE) {+		rc = test_and_set_bit_lock(IDE_HOST_BUSY, &host->host_busy);+		if (rc == 0) {+			/* for atari only */+			ide_get_lock(ide_intr, hwif);+		}+	}+	return rc;+}++static inline void ide_unlock_host(struct ide_host *host)+{+	if (host->host_flags & IDE_HFLAG_SERIALIZE) {+		/* for atari only */+		ide_release_lock();+		clear_bit_unlock(IDE_HOST_BUSY, &host->host_busy);+	}+}+ /*  * Issue a new request to a drive from hwgroup- *- * A hwgroup is a serialized group of IDE interfaces.  Usually there is- * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640)- * may have both interfaces in a single hwgroup to "serialize" access.- * Or possibly multiple ISA interfaces can share a common IRQ by being grouped- * together into one hwgroup for serialized access.- *- * Note also that several hwgroups can end up sharing a single IRQ,- * possibly along with many other devices.  This is especially common in- * PCI-based systems with off-board IDE controller cards.- *- * The IDE driver uses a per-hwgroup lock to protect the hwgroup->busy flag.- *- * The first thread into the driver for a particular hwgroup sets the- * hwgroup->busy flag to indicate that this hwgroup is now active,- * and then initiates processing of the top request from the request queue.- *- * Other threads attempting entry notice the busy setting, and will simply- * queue their new requests and exit immediately.  Note that hwgroup->busy- * remains set even when the driver is merely awaiting the next interrupt.- * Thus, the meaning is "this hwgroup is busy processing a request".- *- * When processing of a request completes, the completing thread or IRQ-handler- * will start the next request from the queue.  If no more work remains,- * the driver will clear the hwgroup->busy flag and exit.- *- * The per-hwgroup spinlock is used to protect all access to the- * hwgroup->busy flag, but is otherwise not needed for most processing in- * the driver.  This makes the driver much more friendlier to shared IRQs- * than previous designs, while remaining 100% (?) SMP safe and capable.  */ void do_ide_request(struct request_queue *q) { 	ide_drive_t	*drive = q->queuedata; 	ide_hwif_t	*hwif = drive->hwif;+	struct ide_host *host = hwif->host; 	ide_hwgroup_t	*hwgroup = hwif->hwgroup;-	struct request	*rq;+	struct request	*rq = NULL; 	ide_startstop_t	startstop;  	/*@@ -721,9 +730,13 @@ void do_ide_request(struct request_queue 		blk_remove_plug(q);  	spin_unlock_irq(q->queue_lock);++	if (ide_lock_host(host, hwif))+		goto plug_device_2;+ 	spin_lock_irq(&hwgroup->lock); -	if (!ide_lock_hwgroup(hwgroup, hwif)) {+	if (!ide_lock_port(hwif)) { 		ide_hwif_t *prev_port; repeat: 		prev_port = hwif->host->cur_port;@@ -731,7 +744,7 @@ repeat:  		if (drive->dev_flags & IDE_DFLAG_SLEEPING) { 			if (time_before(drive->sleep, jiffies)) {-				ide_unlock_hwgroup(hwgroup);+				ide_unlock_port(hwif); 				goto plug_device; 			} 		}@@ -761,7 +774,7 @@ repeat: 		spin_lock_irq(&hwgroup->lock);  		if (!rq) {-			ide_unlock_hwgroup(hwgroup);+			ide_unlock_port(hwif); 			goto out; 		} @@ -782,7 +795,7 @@ repeat: 		    blk_pm_request(rq) == 0 && 		    (rq->cmd_flags & REQ_PREEMPT) == 0) { 			/* there should be no pending command at this point */-			ide_unlock_hwgroup(hwgroup);+			ide_unlock_port(hwif); 			goto plug_device; 		} @@ -798,11 +811,15 @@ repeat: 		goto plug_device; out: 	spin_unlock_irq(&hwgroup->lock);+	if (rq == NULL)+		ide_unlock_host(host); 	spin_lock_irq(q->queue_lock); 	return;  plug_device: 	spin_unlock_irq(&hwgroup->lock);+	ide_unlock_host(host);+plug_device_2: 	spin_lock_irq(q->queue_lock);  	if (!elv_queue_empty(q))@@ -844,9 +861,9 @@ static ide_startstop_t ide_dma_timeout_r 	ide_dma_off_quietly(drive);  	/*-	 * un-busy drive etc (hwgroup->busy is cleared on return) and-	 * make sure request is sane+	 * un-busy drive etc and make sure request is sane 	 */+ 	rq = HWGROUP(drive)->rq;  	if (!rq)@@ -895,6 +912,7 @@ static void ide_plug_device(ide_drive_t  void ide_timer_expiry (unsigned long data) { 	ide_hwgroup_t	*hwgroup = (ide_hwgroup_t *) data;+	ide_hwif_t	*uninitialized_var(hwif); 	ide_drive_t	*uninitialized_var(drive); 	ide_handler_t	*handler; 	ide_expiry_t	*expiry;@@ -918,7 +936,6 @@ void ide_timer_expiry (unsigned long dat 			printk(KERN_ERR "%s: ->cur_dev was NULL\n", __func__); 			hwgroup->handler = NULL; 		} else {-			ide_hwif_t *hwif; 			ide_startstop_t startstop = ide_stopped;  			if ((expiry = hwgroup->expiry) != NULL) {@@ -964,15 +981,17 @@ void ide_timer_expiry (unsigned long dat 			spin_lock_irq(&hwgroup->lock); 			enable_irq(hwif->irq); 			if (startstop == ide_stopped) {-				ide_unlock_hwgroup(hwgroup);+				ide_unlock_port(hwif); 				plug_device = 1; 			} 		} 	} 	spin_unlock_irqrestore(&hwgroup->lock, flags); -	if (plug_device)+	if (plug_device) {+		ide_unlock_host(hwif->host); 		ide_plug_device(drive);+	} }  /**@@ -1150,7 +1169,7 @@ irqreturn_t ide_intr (int irq, void *dev 	 */ 	if (startstop == ide_stopped) { 		if (hwgroup->handler == NULL) {	/* paranoia */-			ide_unlock_hwgroup(hwgroup);+			ide_unlock_port(hwif); 			plug_device = 1; 		} else 			printk(KERN_ERR "%s: %s: huh? expected NULL handler "@@ -1161,8 +1180,10 @@ out_handled: out: 	spin_unlock_irqrestore(&hwgroup->lock, flags); out_early:-	if (plug_device)+	if (plug_device) {+		ide_unlock_host(hwif->host); 		ide_plug_device(drive);+	}  	return irq_ret; }Index: b/include/linux/ide.h===================================================================--- a/include/linux/ide.h+++ b/include/linux/ide.h@@ -828,6 +828,7 @@ typedef struct hwif_s {  	unsigned	present    : 1;	/* this interface exists */ 	unsigned	sg_mapped  : 1;	/* sg_table and sg_nents are ready */+	unsigned	busy	   : 1; /* serializes devices on a port */  	struct device		gendev; 	struct device		*portdev;@@ -851,8 +852,13 @@ struct ide_host { 	unsigned long	host_flags; 	void		*host_priv; 	ide_hwif_t	*cur_port;	/* for hosts requiring serialization */++	/* used for hosts requiring serialization */+	volatile long	host_busy; }; +#define IDE_HOST_BUSY 0+ /*  *  internal ide interrupt handler type  */@@ -866,8 +872,6 @@ typedef struct hwgroup_s { 		/* irq handler, if active */ 	ide_startstop_t	(*handler)(ide_drive_t *); -		/* BOOL: protects all fields below */-	volatile int busy; 		/* BOOL: polling active & poll_timeout field valid */ 	unsigned int polling	: 1; @@ -1271,26 +1275,6 @@ extern void ide_stall_queue(ide_drive_t   extern void ide_timer_expiry(unsigned long); extern irqreturn_t ide_intr(int irq, void *dev_id);--static inline int ide_lock_hwgroup(ide_hwgroup_t *hwgroup, ide_hwif_t *hwif)-{-	if (hwgroup->busy)-		return 1;--	hwgroup->busy = 1;-	/* for atari only */-	ide_get_lock(ide_intr, hwif);--	return 0;-}--static inline void ide_unlock_hwgroup(ide_hwgroup_t *hwgroup)-{-	/* for atari only */-	ide_release_lock();-	hwgroup->busy = 0;-}- extern void do_ide_request(struct request_queue *);  void ide_init_disk(struct gendisk *, ide_drive_t *);@@ -1617,13 +1601,6 @@ static inline void ide_set_max_pio(ide_d  extern spinlock_t ide_lock; extern struct mutex ide_cfg_mtx;-/*- * Structure locking:- *- * ide_hwgroup_t->busy: hwgroup->lock- * ide_hwif_t->{hwgroup,mate}: constant, no locking- * ide_drive_t->hwif: constant, no locking- */  #define local_irq_set(flags)	do { local_save_flags((flags)); local_irq_enable_in_hardirq(); } while (0) \0ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

             reply	other threads:[~2008-12-21 20:57 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-12-21 20:56 Bartlomiej Zolnierkiewicz [this message]
2008-12-21 20:56 ` [PATCH] ide: use lock bitops for ports serialization (v2) Bartlomiej Zolnierkiewicz

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=200812212156.08723.bzolnier@gmail.com \
    --to=bzolnier@gmail.com \
    --cc=linux-ide@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.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.