[linux-yocto] [[PATCH 1/1] scsi: add extended information to MEDIA_CHANGE
chong.yi.chai at intel.com
chong.yi.chai at intel.com
Wed Mar 30 20:17:26 PDT 2016
From: "Chai, Chong Yi" <chong.yi.chai at intel.com>
---
features/soc/baytrail/baytrail.scc | 1 +
...-add-extended-information-to-MEDIA_CHANGE.patch | 183 +++++++++++++++++++++
2 files changed, 184 insertions(+)
create mode 100644 features/soc/baytrail/scsi-add-extended-information-to-MEDIA_CHANGE.patch
diff --git a/features/soc/baytrail/baytrail.scc b/features/soc/baytrail/baytrail.scc
index 4b71e0f..a1d8688 100644
--- a/features/soc/baytrail/baytrail.scc
+++ b/features/soc/baytrail/baytrail.scc
@@ -73,3 +73,4 @@ patch pinctrl-baytrail-enable-platform-device-in-the-absen.patch
patch pinctrl-baytrail-setup-IOAPIC-interrupt-for-GPIO-clu.patch
patch pinctrl-baytrail-Serialize-GPIO-registers-access-wit.patch
patch pwm-Add-freq_hz-and-duty_percent.patch
+patch scsi-add-extended-information-to-MEDIA_CHANGE.patch
diff --git a/features/soc/baytrail/scsi-add-extended-information-to-MEDIA_CHANGE.patch b/features/soc/baytrail/scsi-add-extended-information-to-MEDIA_CHANGE.patch
new file mode 100644
index 0000000..473a508
--- /dev/null
+++ b/features/soc/baytrail/scsi-add-extended-information-to-MEDIA_CHANGE.patch
@@ -0,0 +1,183 @@
+From d5bb90a095d67814035b2202f97f49048d258f1e Mon Sep 17 00:00:00 2001
+From: Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad at intel.com>
+Date: Wed, 29 Jul 2015 18:13:44 +0800
+Subject: [PATCH 117/164] scsi: add extended information to MEDIA_CHANGE
+
+Add media change reason string to SDEV_MEDIA_CHANGE uevent
+in the format of "SDEV_MEDIA_CHANGE_REASON=<reason>, where
+reason is one of MEDIA_DETACH, MEDIA_ATTACH and MEDIA_BAD.
+
+Signed-off-by: Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad at intel.com>
+---
+ drivers/scsi/scsi_lib.c | 80 ++++++++++++++++++++++++++++++++++++++++++++
+ drivers/scsi/sr.c | 8 ++++
+ include/scsi/scsi_device.h | 18 ++++++++++
+ 3 files changed, 106 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index 719bd82..5543d4b 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -2225,6 +2225,78 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)
+ }
+ EXPORT_SYMBOL(scsi_device_set_state);
+
++#define MAX_RETRIES 3
++#define SR_TIMEOUT (3 * HZ)
++
++/**
++ * get_change_reason - Obtain media change reason by querying the device
++ * @sdev: scsi device to get media change reason from.
++ *
++ * Returns reason as specified in @scsi_media_change_reason
++ */
++static enum scsi_media_change_reason get_change_reason(struct scsi_device *sdev)
++{
++ int ret, is_good;
++ enum scsi_media_change_reason reason = SDEV_MEDIA_UNDEF;
++ struct scsi_sense_hdr sshdr;
++
++ ret = scsi_test_unit_ready(sdev, SR_TIMEOUT, MAX_RETRIES, &sshdr);
++ is_good = scsi_status_is_good(ret);
++ pr_debug("%s: changed %d, is_good %d, asc 0x%x, ascq 0x%x\n",
++ __func__, sdev->changed, is_good, sshdr.asc, sshdr.ascq);
++
++ if (is_good)
++ reason = SDEV_MEDIA_ATTACH;
++ else {
++ /*
++ * This is part of custom requirement for Bay Trail customer.
++ * The driver shall issue a notification event in case of
++ * media insertion and removal. The event which is sent
++ * represents the current notification status and shall be
++ * one of: ATTACH, BAD_MEDIA, EJECT.
++ */
++ switch (sshdr.asc) {
++ /* ASC code 0x28: Not ready to ready change, medium may have
++ * changed
++ * ASC code 0x29: Power on, reset, or bus device reset
++ * occured
++ */
++ case 0x28:
++ case 0x29:
++ reason = SDEV_MEDIA_UNDEF;
++ break;
++ /* ASC code 0x04: Logical Unit Not Ready/Not Accessible */
++ case 0x04:
++ if (sshdr.ascq == 0x01) {
++ reason = SDEV_MEDIA_UNDEF;
++ break;
++ }
++ /* otherwise fall through */
++ /* ASC code 0x3A - Medium Not Present */
++ case 0x3A:
++ reason = SDEV_MEDIA_DETACH;
++ break;
++
++ default:
++ reason = SDEV_MEDIA_BAD;
++ break;
++ }
++ }
++
++ if (!sdev->changed && reason == sdev->last_change_reason)
++ reason = SDEV_MEDIA_UNDEF;
++ else
++ sdev->last_change_reason = reason;
++
++ return reason;
++}
++
++static char *media_change_reasons[SDEV_MEDIA_REASON_MAX] = {
++ [SDEV_MEDIA_ATTACH] = "SDEV_MEDIA_CHANGE_REASON=MEDIA_ATTACH",
++ [SDEV_MEDIA_DETACH] = "SDEV_MEDIA_CHANGE_REASON=MEDIA_DETACH",
++ [SDEV_MEDIA_BAD] = "SDEV_MEDIA_CHANGE_REASON=MEDIA_BAD",
++};
++
+ /**
+ * sdev_evt_emit - emit a single SCSI device uevent
+ * @sdev: associated SCSI device
+@@ -2236,10 +2308,18 @@ static void scsi_evt_emit(struct scsi_device *sdev, struct scsi_event *evt)
+ {
+ int idx = 0;
+ char *envp[3];
++ enum scsi_media_change_reason r;
+
+ switch (evt->evt_type) {
+ case SDEV_EVT_MEDIA_CHANGE:
+ envp[idx++] = "SDEV_MEDIA_CHANGE=1";
++ if (sdev->add_change_reason) {
++ r = get_change_reason(sdev);
++ if (media_change_reasons[r])
++ envp[idx++] = media_change_reasons[r];
++ pr_debug("%s: reason %s\n", __func__,
++ media_change_reasons[r] ?: "n/a");
++ }
+ break;
+ case SDEV_EVT_INQUIRY_CHANGE_REPORTED:
+ envp[idx++] = "SDEV_UA=INQUIRY_DATA_HAS_CHANGED";
+diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
+index 40d8592..92ada30 100644
+--- a/drivers/scsi/sr.c
++++ b/drivers/scsi/sr.c
+@@ -740,6 +740,14 @@ static int sr_probe(struct device *dev)
+ disk->flags |= GENHD_FL_REMOVABLE;
+ add_disk(disk);
+
++ /*
++ * Let SCSI add change reason to uevent.
++ * This is a custom requirement from Bay Trail customer,
++ * to have get an event notification of media insertion
++ * and removal.
++ */
++ sdev->add_change_reason = 1;
++
+ sdev_printk(KERN_DEBUG, sdev,
+ "Attached scsi CD-ROM %s\n", cd->cdi.name);
+ scsi_autopm_put_device(cd->device);
+diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
+index 409fafb..ea9bbc4 100644
+--- a/include/scsi/scsi_device.h
++++ b/include/scsi/scsi_device.h
+@@ -64,6 +64,21 @@ enum scsi_device_event {
+ SDEV_EVT_MAXBITS = SDEV_EVT_LAST + 1
+ };
+
++/**
++ * SCSI media change event reasons
++ * @SDEV_MEDIA_ATTACH: a valid medium has been inserted
++ * @SDEV_MEDIA_BAD: an unreadable medium has been inserted into the drive
++ * @SDEV_MEDIA_DETACH: a medium has been removed
++ * @SDEV_MEDIA_UNDEF: no valid reason has been detected
++ */
++enum scsi_media_change_reason {
++ SDEV_MEDIA_ATTACH = 1,
++ SDEV_MEDIA_BAD,
++ SDEV_MEDIA_DETACH,
++ SDEV_MEDIA_UNDEF,
++ SDEV_MEDIA_REASON_MAX = SDEV_MEDIA_UNDEF
++};
++
+ struct scsi_event {
+ enum scsi_device_event evt_type;
+ struct list_head node;
+@@ -168,6 +183,7 @@ struct scsi_device {
+ unsigned is_visible:1; /* is the device visible in sysfs */
+ unsigned wce_default_on:1; /* Cache is ON by default */
+ unsigned no_dif:1; /* T10 PI (DIF) should be disabled */
++ unsigned add_change_reason:1; /* Add media change reason? */
+
+ atomic_t disk_events_disable_depth; /* disable depth for disk events */
+
+@@ -193,6 +209,8 @@ struct scsi_device {
+
+ struct scsi_dh_data *scsi_dh_data;
+ enum scsi_device_state sdev_state;
++
++ enum scsi_media_change_reason last_change_reason;
+ unsigned long sdev_data[0];
+ } __attribute__((aligned(sizeof(unsigned long))));
+
+--
+1.7.7.6
+
--
1.9.1
More information about the linux-yocto
mailing list