Skip to contentSkip to conversation

staging: ks7010: ks_wlan_net: Use netdev_ or pr_info instead of printk

PATCH Superseded Georgiana Rodica Chelu 3 participants 4 messages Sep 23, 2016 – Sep 26, 2016 Staging

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 staging: ks7010: ks_wlan_net: Use netdev_ or pr_info instead of printk

The checkpatch.pl script found the following warning:

WARNING: printk() should include KERN_ facility level

After adding the KERN_ facility level to printk(), the script showed another warning:

WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...

The warning is similar for KERN_ERR and KERN_DEBUG. In conclusion, use netdev_info(), netdev_err() or netdev_dbg() when there is a netdev device and use pr_info() in the remained cases.

---
Changes in v2:
- make the commit message more clear
- replace all the appearances of printk()

 drivers/staging/ks7010/ks_wlan_net.c | 92 ++++++++++++++++++------------------
 1 file changed, 46 insertions(+), 46 deletions(-)
drivers/staging/ks7010/ks_wlan_net.c +46 -46
index d13a06b..9ef44cc 100644
@@ -233,9 +233,9 @@ static int ks_wlan_set_freq(struct net_device *dev,
 		/* We should do a better check than that,
 		 * based on the card capability !!! */
 		if ((channel < 1) || (channel > 14)) {
-			printk(KERN_DEBUG
-			       "%s: New channel value of %d is invalid!\n",
-			       dev->name, fwrq->m);
+			netdev_dbg(dev,
+				   "%s: New channel value of %d is invalid!\n",
+				   dev->name, fwrq->m);
 			rc = -EINVAL;
 		} else {
 			/* Yes ! We can set it !!! */
@@ -2671,17 +2671,17 @@ static int ks_wlan_set_sleep_mode(struct net_device *dev,
 
 	if (*uwrq == SLP_SLEEP) {
 		priv->sleep_mode = *uwrq;
-		printk("SET_SLEEP_MODE %d\n", priv->sleep_mode);
+		netdev_info(dev, "SET_SLEEP_MODE %d\n", priv->sleep_mode);
 
 		hostif_sme_enqueue(priv, SME_STOP_REQUEST);
 		hostif_sme_enqueue(priv, SME_SLEEP_REQUEST);
 
 	} else if (*uwrq == SLP_ACTIVE) {
 		priv->sleep_mode = *uwrq;
-		printk("SET_SLEEP_MODE %d\n", priv->sleep_mode);
+		netdev_info(dev, "SET_SLEEP_MODE %d\n", priv->sleep_mode);
 		hostif_sme_enqueue(priv, SME_SLEEP_REQUEST);
 	} else {
-		printk("SET_SLEEP_MODE %d errror\n", *uwrq);
+		netdev_err(dev, "SET_SLEEP_MODE %d errror\n", *uwrq);
 		return -EINVAL;
 	}
 
@@ -2783,7 +2783,7 @@ static int ks_wlan_get_wps_enable(struct net_device *dev,
 	}
 	/* for SLEEP MODE */
 	*uwrq = priv->wps.wps_enabled;
-	printk("return=%d\n", *uwrq);
+	netdev_info(dev, "return=%d\n", *uwrq);
 
 	return 0;
 }
@@ -2978,112 +2978,112 @@ static void print_hif_event(int event)
 
 	switch (event) {
 	case HIF_DATA_REQ:
-		printk("HIF_DATA_REQ\n");
+		pr_info("HIF_DATA_REQ\n");
 		break;
 	case HIF_DATA_IND:
-		printk("HIF_DATA_IND\n");
+		pr_info("HIF_DATA_IND\n");
 		break;
 	case HIF_MIB_GET_REQ:
-		printk("HIF_MIB_GET_REQ\n");
+		pr_info("HIF_MIB_GET_REQ\n");
 		break;
 	case HIF_MIB_GET_CONF:
-		printk("HIF_MIB_GET_CONF\n");
+		pr_info("HIF_MIB_GET_CONF\n");
 		break;
 	case HIF_MIB_SET_REQ:
-		printk("HIF_MIB_SET_REQ\n");
+		pr_info("HIF_MIB_SET_REQ\n");
 		break;
 	case HIF_MIB_SET_CONF:
-		printk("HIF_MIB_SET_CONF\n");
+		pr_info("HIF_MIB_SET_CONF\n");
 		break;
 	case HIF_POWERMGT_REQ:
-		printk("HIF_POWERMGT_REQ\n");
+		pr_info("HIF_POWERMGT_REQ\n");
 		break;
 	case HIF_POWERMGT_CONF:
-		printk("HIF_POWERMGT_CONF\n");
+		pr_info("HIF_POWERMGT_CONF\n");
 		break;
 	case HIF_START_REQ:
-		printk("HIF_START_REQ\n");
+		pr_info("HIF_START_REQ\n");
 		break;
 	case HIF_START_CONF:
-		printk("HIF_START_CONF\n");
+		pr_info("HIF_START_CONF\n");
 		break;
 	case HIF_CONNECT_IND:
-		printk("HIF_CONNECT_IND\n");
+		pr_info("HIF_CONNECT_IND\n");
 		break;
 	case HIF_STOP_REQ:
-		printk("HIF_STOP_REQ\n");
+		pr_info("HIF_STOP_REQ\n");
 		break;
 	case HIF_STOP_CONF:
-		printk("HIF_STOP_CONF\n");
+		pr_info("HIF_STOP_CONF\n");
 		break;
 	case HIF_PS_ADH_SET_REQ:
-		printk("HIF_PS_ADH_SET_REQ\n");
+		pr_info("HIF_PS_ADH_SET_REQ\n");
 		break;
 	case HIF_PS_ADH_SET_CONF:
-		printk("HIF_PS_ADH_SET_CONF\n");
+		pr_info("HIF_PS_ADH_SET_CONF\n");
 		break;
 	case HIF_INFRA_SET_REQ:
-		printk("HIF_INFRA_SET_REQ\n");
+		pr_info("HIF_INFRA_SET_REQ\n");
 		break;
 	case HIF_INFRA_SET_CONF:
-		printk("HIF_INFRA_SET_CONF\n");
+		pr_info("HIF_INFRA_SET_CONF\n");
 		break;
 	case HIF_ADH_SET_REQ:
-		printk("HIF_ADH_SET_REQ\n");
+		pr_info("HIF_ADH_SET_REQ\n");
 		break;
 	case HIF_ADH_SET_CONF:
-		printk("HIF_ADH_SET_CONF\n");
+		pr_info("HIF_ADH_SET_CONF\n");
 		break;
 	case HIF_AP_SET_REQ:
-		printk("HIF_AP_SET_REQ\n");
+		pr_info("HIF_AP_SET_REQ\n");
 		break;
 	case HIF_AP_SET_CONF:
-		printk("HIF_AP_SET_CONF\n");
+		pr_info("HIF_AP_SET_CONF\n");
 		break;
 	case HIF_ASSOC_INFO_IND:
-		printk("HIF_ASSOC_INFO_IND\n");
+		pr_info("HIF_ASSOC_INFO_IND\n");
 		break;
 	case HIF_MIC_FAILURE_REQ:
-		printk("HIF_MIC_FAILURE_REQ\n");
+		pr_info("HIF_MIC_FAILURE_REQ\n");
 		break;
 	case HIF_MIC_FAILURE_CONF:
-		printk("HIF_MIC_FAILURE_CONF\n");
+		pr_info("HIF_MIC_FAILURE_CONF\n");
 		break;
 	case HIF_SCAN_REQ:
-		printk("HIF_SCAN_REQ\n");
+		pr_info("HIF_SCAN_REQ\n");
 		break;
 	case HIF_SCAN_CONF:
-		printk("HIF_SCAN_CONF\n");
+		pr_info("HIF_SCAN_CONF\n");
 		break;
 	case HIF_PHY_INFO_REQ:
-		printk("HIF_PHY_INFO_REQ\n");
+		pr_info("HIF_PHY_INFO_REQ\n");
 		break;
 	case HIF_PHY_INFO_CONF:
-		printk("HIF_PHY_INFO_CONF\n");
+		pr_info("HIF_PHY_INFO_CONF\n");
 		break;
 	case HIF_SLEEP_REQ:
-		printk("HIF_SLEEP_REQ\n");
+		pr_info("HIF_SLEEP_REQ\n");
 		break;
 	case HIF_SLEEP_CONF:
-		printk("HIF_SLEEP_CONF\n");
+		pr_info("HIF_SLEEP_CONF\n");
 		break;
 	case HIF_PHY_INFO_IND:
-		printk("HIF_PHY_INFO_IND\n");
+		pr_info("HIF_PHY_INFO_IND\n");
 		break;
 	case HIF_SCAN_IND:
-		printk("HIF_SCAN_IND\n");
+		pr_info("HIF_SCAN_IND\n");
 		break;
 	case HIF_INFRA_SET2_REQ:
-		printk("HIF_INFRA_SET2_REQ\n");
+		pr_info("HIF_INFRA_SET2_REQ\n");
 		break;
 	case HIF_INFRA_SET2_CONF:
-		printk("HIF_INFRA_SET2_CONF\n");
+		pr_info("HIF_INFRA_SET2_CONF\n");
 		break;
 	case HIF_ADH_SET2_REQ:
-		printk("HIF_ADH_SET2_REQ\n");
+		pr_info("HIF_ADH_SET2_REQ\n");
 		break;
 	case HIF_ADH_SET2_CONF:
-		printk("HIF_ADH_SET2_CONF\n");
+		pr_info("HIF_ADH_SET2_CONF\n");
 	}
 }
 
@@ -3330,7 +3330,7 @@ int ks_wlan_set_mac_address(struct net_device *dev, void *addr)
 
 	priv->mac_address_valid = 0;
 	hostif_sme_enqueue(priv, SME_MACADDRESS_SET_REQUEST);
-	printk(KERN_INFO
+	netdev_info(dev,
 	       "ks_wlan: MAC ADDRESS = %02x:%02x:%02x:%02x:%02x:%02x\n",
 	       priv->eth_addr[0], priv->eth_addr[1], priv->eth_addr[2],
 	       priv->eth_addr[3], priv->eth_addr[4], priv->eth_addr[5]);
@@ -3362,7 +3362,7 @@ int ks_wlan_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	DPRINTK(3, "in_interrupt()=%ld\n", in_interrupt());
 
 	if (!skb) {
-		printk(KERN_ERR "ks_wlan:  skb == NULL!!!\n");
+		netdev_err(dev, "ks_wlan:  skb == NULL!!!\n");
 		return 0;
 	}
 	if (priv->dev_state < DEVICE_STATE_READY) {
@@ -3428,7 +3428,7 @@ int ks_wlan_open(struct net_device *dev)
 	priv->cur_rx = 0;
 
 	if (!priv->mac_address_valid) {
-		printk(KERN_ERR "ks_wlan : %s Not READY !!\n", dev->name);
+		netdev_err(dev, "ks_wlan : %s Not READY !!\n", dev->name);
 		return -EBUSY;
 	} else
 		netif_start_queue(dev);
Signature · 1 line
2.7.4
maintainer
#1 lore raw
Quoted 71 lines · Georgiana Rodica Chelu

The checkpatch.pl script found the following warning:

WARNING: printk() should include KERN_ facility level

After adding the KERN_ facility level to printk(), the script showed another warning:

WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...

The warning is similar for KERN_ERR and KERN_DEBUG. In conclusion, use netdev_info(), netdev_err() or netdev_dbg() when there is a netdev device and use pr_info() in the remained cases.

---
Changes in v2:
- make the commit message more clear
- replace all the appearances of printk()

 drivers/staging/ks7010/ks_wlan_net.c | 92 ++++++++++++++++++------------------
 1 file changed, 46 insertions(+), 46 deletions(-)
drivers/staging/ks7010/ks_wlan_net.c +7 -7
index d13a06b..9ef44cc 100644
@@ -233,9 +233,9 @@ static int ks_wlan_set_freq(struct net_device *dev,
 		/* We should do a better check than that,
 		 * based on the card capability !!! */
 		if ((channel < 1) || (channel > 14)) {
-			printk(KERN_DEBUG
-			       "%s: New channel value of %d is invalid!\n",
-			       dev->name, fwrq->m);
+			netdev_dbg(dev,
+				   "%s: New channel value of %d is invalid!\n",
+				   dev->name, fwrq->m);
 			rc = -EINVAL;
 		} else {
 			/* Yes ! We can set it !!! */
@@ -2671,17 +2671,17 @@ static int ks_wlan_set_sleep_mode(struct net_device *dev,
 
 	if (*uwrq == SLP_SLEEP) {
 		priv->sleep_mode = *uwrq;
-		printk("SET_SLEEP_MODE %d\n", priv->sleep_mode);
+		netdev_info(dev, "SET_SLEEP_MODE %d\n", priv->sleep_mode);
 
 		hostif_sme_enqueue(priv, SME_STOP_REQUEST);
 		hostif_sme_enqueue(priv, SME_SLEEP_REQUEST);
 
 	} else if (*uwrq == SLP_ACTIVE) {
 		priv->sleep_mode = *uwrq;
-		printk("SET_SLEEP_MODE %d\n", priv->sleep_mode);
+		netdev_info(dev, "SET_SLEEP_MODE %d\n", priv->sleep_mode);
 		hostif_sme_enqueue(priv, SME_SLEEP_REQUEST);
 	} else {
-		printk("SET_SLEEP_MODE %d errror\n", *uwrq);
+		netdev_err(dev, "SET_SLEEP_MODE %d errror\n", *uwrq);
 		return -EINVAL;
 	}
 
@@ -2783,7 +2783,7 @@ static int ks_wlan_get_wps_enable(struct net_device *dev,
 	}
 	/* for SLEEP MODE */
 	*uwrq = priv->wps.wps_enabled;
-	printk("return=%d\n", *uwrq);
+	netdev_info(dev, "return=%d\n", *uwrq);
 
 	return 0;
 }

drivers/staging/ks7010/ks_wlan_net.c static void print_hif_event(int event) · line 2984

Quoted 9 lines
drivers/staging/ks7010/ks_wlan_net.c +2 -2
@@ -2978,112 +2978,112 @@ static void print_hif_event(int event)
 
 	switch (event) {
 	case HIF_DATA_REQ:
-		printk("HIF_DATA_REQ\n");
+		pr_info("HIF_DATA_REQ\n");
 		break;
 	case HIF_DATA_IND:
-		printk("HIF_DATA_IND\n");
+		pr_info("HIF_DATA_IND\n");

All of these should have a device structure somewhere, please fix this function up to have that. Right now I'd just take these changes out of the patch and submit the rest.

thanks,

greg k-h

#2 lore raw

I submitted the third version of the patch. I had to change the title, so the patch will not appear in this thread.

About the function static void print_hif_event(int event); I have no clue how to find the device structure. Could you give me some hints?

Thank you,
Georgiana

Quoted 95 lines · Greg KH
Quoted 14 lines · Georgiana Rodica Chelu

The checkpatch.pl script found the following warning:

WARNING: printk() should include KERN_ facility level

After adding the KERN_ facility level to printk(), the script showed another warning:

WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...

The warning is similar for KERN_ERR and KERN_DEBUG. In conclusion, use netdev_info(), netdev_err() or netdev_dbg() when there is a netdev device and use pr_info() in the remained cases.

Quoted 7 lines

---
Changes in v2:
- make the commit message more clear
- replace all the appearances of printk()

 drivers/staging/ks7010/ks_wlan_net.c | 92

++++++++++++++++++------------------

Review

Quoted 3 lines
 1 file changed, 46 insertions(+), 46 deletions(-)
(quoted diff) +0 -0

b/drivers/staging/ks7010/ks_wlan_net.c

drivers/staging/ks7010/ks_wlan_net.c static int ks_wlan_set_freq(struct net_device *dev, · line 237

Quoted 12 lines

index d13a06b..9ef44cc 100644

drivers/staging/ks7010/ks_wlan_net.c +2 -3
@@ -233,9 +233,9 @@ static int ks_wlan_set_freq(struct net_device *dev,
              /* We should do a better check than that,
               * based on the card capability !!! */
              if ((channel < 1) || (channel > 14)) {
-                     printk(KERN_DEBUG
-                            "%s: New channel value of %d is invalid!\n",
-                            dev->name, fwrq->m);
+                     netdev_dbg(dev,
+                                "%s: New channel value of %d is

invalid!\n",

drivers/staging/ks7010/ks_wlan_net.c static int ks_wlan_set_sleep_mode(struct

Quoted 5 lines
drivers/staging/ks7010/ks_wlan_net.c +1 -0
+                                dev->name, fwrq->m);
                      rc = -EINVAL;
              } else {
                      /* Yes ! We can set it !!! */
@@ -2671,17 +2671,17 @@ static int ks_wlan_set_sleep_mode(struct

net_device *dev,

drivers/staging/ks7010/ks_wlan_net.c static int ks_wlan_get_wps_enable(struct

Quoted 21 lines
drivers/staging/ks7010/ks_wlan_net.c +3 -3
      if (*uwrq == SLP_SLEEP) {
              priv->sleep_mode = *uwrq;
-             printk("SET_SLEEP_MODE %d\n", priv->sleep_mode);
+             netdev_info(dev, "SET_SLEEP_MODE %d\n", priv->sleep_mode);
 
              hostif_sme_enqueue(priv, SME_STOP_REQUEST);
              hostif_sme_enqueue(priv, SME_SLEEP_REQUEST);
 
      } else if (*uwrq == SLP_ACTIVE) {
              priv->sleep_mode = *uwrq;
-             printk("SET_SLEEP_MODE %d\n", priv->sleep_mode);
+             netdev_info(dev, "SET_SLEEP_MODE %d\n", priv->sleep_mode);
              hostif_sme_enqueue(priv, SME_SLEEP_REQUEST);
      } else {
-             printk("SET_SLEEP_MODE %d errror\n", *uwrq);
+             netdev_err(dev, "SET_SLEEP_MODE %d errror\n", *uwrq);
              return -EINVAL;
      }
 
@@ -2783,7 +2783,7 @@ static int ks_wlan_get_wps_enable(struct

net_device *dev,

Quoted 9 lines
drivers/staging/ks7010/ks_wlan_net.c +1 -1
      }
      /* for SLEEP MODE */
      *uwrq = priv->wps.wps_enabled;
-     printk("return=%d\n", *uwrq);
+     netdev_info(dev, "return=%d\n", *uwrq);
 
      return 0;
 }

drivers/staging/ks7010/ks_wlan_net.c static void print_hif_event(int event) · line 2984

Quoted 9 lines
drivers/staging/ks7010/ks_wlan_net.c +2 -2
@@ -2978,112 +2978,112 @@ static void print_hif_event(int event)
 
      switch (event) {
      case HIF_DATA_REQ:
-             printk("HIF_DATA_REQ\n");
+             pr_info("HIF_DATA_REQ\n");
              break;
      case HIF_DATA_IND:
-             printk("HIF_DATA_IND\n");
+             pr_info("HIF_DATA_IND\n");

All of these should have a device structure somewhere, please fix this function up to have that. Right now I'd just take these changes out of the patch and submit the rest.

thanks,

greg k-h

#3 lore raw
Quoted 5 lines · Georgiana Chelu

I submitted the third version of the patch. I had to change the title, so the patch will not appear in this thread.

About the function static void print_hif_event(int event); I have no clue how to find the device structure. Could you give me some hints?

Look at the call sites of print_hif_event and see if there is some argument you could add that would provide the needed information.

julia

Quoted 124 lines

Thank you,
Georgiana

On 25 September 2016 at 13:35, Greg KH <[email protected]> wrote:

      On Sat, Sep 24, 2016 at 12:33:43AM +0300, Georgiana Rodica Chelu
      wrote:
      > The checkpatch.pl script found the following warning:
      >
      > WARNING: printk() should include KERN_ facility level
      >
      > After adding the KERN_ facility level to printk(), the script
      showed
      > another warning:
      >
      > WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev,
      ... then
      > dev_info(dev, ... then pr_info(...  to printk(KERN_INFO ...
      >
      > The warning is similar for KERN_ERR and KERN_DEBUG. In
      conclusion,
      > use netdev_info(), netdev_err() or netdev_dbg() when there is
      > a netdev device and use pr_info() in the remained cases.
      >
      > Signed-off-by: Georgiana Rodica Chelu
      <[email protected]>
      > ---
      > Changes in v2:
      >         - make the commit message more clear
      >       - replace all the appearances of printk()
      >
      >  drivers/staging/ks7010/ks_wlan_net.c | 92
      ++++++++++++++++++------------------
      >  1 file changed, 46 insertions(+), 46 deletions(-)
      >
      > diff --git a/drivers/staging/ks7010/ks_wlan_net.c
      b/drivers/staging/ks7010/ks_wlan_net.c
      > index d13a06b..9ef44cc 100644
      > --- a/drivers/staging/ks7010/ks_wlan_net.c
      > +++ b/drivers/staging/ks7010/ks_wlan_net.c
      > @@ -233,9 +233,9 @@ static int ks_wlan_set_freq(struct
      net_device *dev,
      >               /* We should do a better check than that,
      >                * based on the card capability !!! */
      >               if ((channel < 1) || (channel > 14)) {
      > -                     printk(KERN_DEBUG
      > -                            "%s: New channel value of %d is
      invalid!\n",
      > -                            dev->name, fwrq->m);
      > +                     netdev_dbg(dev,
      > +                                "%s: New channel value of %d
      is invalid!\n",
      > +                                dev->name, fwrq->m);
      >                       rc = -EINVAL;
      >               } else {
      >                       /* Yes ! We can set it !!! */
      > @@ -2671,17 +2671,17 @@ static int
      ks_wlan_set_sleep_mode(struct net_device *dev,
      >
      >       if (*uwrq == SLP_SLEEP) {
      >               priv->sleep_mode = *uwrq;
      > -             printk("SET_SLEEP_MODE %d\n", priv->sleep_mode);
      > +             netdev_info(dev, "SET_SLEEP_MODE %d\n",
      priv->sleep_mode);
      >
      >               hostif_sme_enqueue(priv, SME_STOP_REQUEST);
      >               hostif_sme_enqueue(priv, SME_SLEEP_REQUEST);
      >
      >       } else if (*uwrq == SLP_ACTIVE) {
      >               priv->sleep_mode = *uwrq;
      > -             printk("SET_SLEEP_MODE %d\n", priv->sleep_mode);
      > +             netdev_info(dev, "SET_SLEEP_MODE %d\n",
      priv->sleep_mode);
      >               hostif_sme_enqueue(priv, SME_SLEEP_REQUEST);
      >       } else {
      > -             printk("SET_SLEEP_MODE %d errror\n", *uwrq);
      > +             netdev_err(dev, "SET_SLEEP_MODE %d errror\n",
      *uwrq);
      >               return -EINVAL;
      >       }
      >
      > @@ -2783,7 +2783,7 @@ static int ks_wlan_get_wps_enable(struct
      net_device *dev,
      >       }
      >       /* for SLEEP MODE */
      >       *uwrq = priv->wps.wps_enabled;
      > -     printk("return=%d\n", *uwrq);
      > +     netdev_info(dev, "return=%d\n", *uwrq);
      >
      >       return 0;
      >  }
      > @@ -2978,112 +2978,112 @@ static void print_hif_event(int
      event)
      >
      >       switch (event) {
      >       case HIF_DATA_REQ:
      > -             printk("HIF_DATA_REQ\n");
      > +             pr_info("HIF_DATA_REQ\n");
      >               break;
      >       case HIF_DATA_IND:
      > -             printk("HIF_DATA_IND\n");
      > +             pr_info("HIF_DATA_IND\n");

All of these should have a device structure somewhere, please fix this function up to have that.  Right now I'd just take these changes out of
the patch and submit the rest.

thanks,

greg k-h

--
You received this message because you are subscribed to the Google Groups
"outreachy-kernel" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visithttps://groups.google.com/d/msgid/outreachy-kernel/CALta04y3Z_12G_7Gcv%3D65 Z9Qb1Hc8UkJ0B4UMVfjQZz9HuKhxw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.