<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/">
  <channel rdf:about="http://blog.gmane.org/gmane.linux.scsi">
    <title>gmane.linux.scsi</title>
    <link>http://blog.gmane.org/gmane.linux.scsi</link>
    <description/>
    <syn:updatePeriod>hourly</syn:updatePeriod>
    <syn:updateFrequency>1</syn:updateFrequency>
    <syn:updateBase>1901-01-01T00:00+00:00</syn:updateBase>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82099"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82098"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82093"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82091"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82090"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82089"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82088"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82087"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82086"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82085"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82084"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82083"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82082"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82081"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82080"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82079"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82078"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82077"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82076"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.scsi/82075"/>
      </rdf:Seq>
    </items>
    <image rdf:resource="http://gmane.org/img/gmane-25t.png"/>
    <textinput rdf:resource=""/>
  </channel>
  <image rdf:about="http://gmane.org/img/gmane-25t.png">
    <title>Gmane</title>
    <url>http://gmane.org/img/gmane-25t.png</url>
    <link>http://gmane.org</link>
  </image>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82099">
    <title>Contact me</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82099</link>
    <description>&lt;pre&gt;


Good Day,

   I have a secured business proposal for you. contact me  for more
details of my Business Proposal.

  Your earliest response to this letter will be appreciated.
Yours Sincerely,
Mrs.Kang.


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo&amp;lt; at &amp;gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>Kang Teobeng</dc:creator>
    <dc:date>2013-05-20T11:15:53</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82098">
    <title>CHECK.</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82098</link>
    <description>&lt;pre&gt;

Attention,

Important message from ADMIN- Please confirm your email address by
clicking this link:

http://feedbck.jimdo.com/

Webmaster


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo&amp;lt; at &amp;gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>Help Desk</dc:creator>
    <dc:date>2013-05-20T08:54:48</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82093">
    <title>[PATCH 1/5] scsi: rename return code FAST_IO_FAIL to FAST_IO</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82093</link>
    <description>&lt;pre&gt;The return code FAST_IO_FAIL was introduced for fast failed io
recovery. To use this code for fast timed-out io recovery as well,
we'd rename it to FAST_IO.

Signed-off-by: Ren Mingxin &amp;lt;renmx&amp;lt; at &amp;gt;cn.fujitsu.com&amp;gt;
---
 drivers/scsi/scsi_error.c           |   18 +++++++++---------
 drivers/scsi/scsi_transport_fc.c    |    4 ++--
 drivers/scsi/scsi_transport_iscsi.c |    6 +++---
 include/scsi/scsi.h                 |    2 +-
 4 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index f43de1e..9e8e37a 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1067,9 +1067,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int scsi_eh_abort_cmds(struct list_head *work_q,
   "0x%p\n", current-&amp;gt;comm,
   scmd));
 rtn = scsi_try_to_abort_cmd(scmd-&amp;gt;device-&amp;gt;host-&amp;gt;hostt, scmd);
-if (rtn == SUCCESS || rtn == FAST_IO_FAIL) {
+if (rtn == SUCCESS || rtn == FAST_IO) {
 scmd-&amp;gt;eh_eflags &amp;amp;= ~SCSI_EH_CANCEL_CMD;
-if (rtn == FAST_IO_FAIL)
+if (rtn == FAST_IO)
 scsi_eh_finish_cmd(scmd, done_q);
 else
 list_move_tail(&amp;amp;scmd-&amp;gt;eh_entry, &amp;amp;check_list);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1195,9 +1195,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int scsi_eh_bus_device_reset(struct Scsi_Host *shost,
   " 0x%p\n", current-&amp;gt;comm,
   sdev));
 rtn = scsi_try_bus_device_reset(bdr_scmd);
-if (rtn == SUCCESS || rtn == FAST_IO_FAIL) {
+if (rtn == SUCCESS || rtn == FAST_IO) {
 if (!scsi_device_online(sdev) ||
-    rtn == FAST_IO_FAIL ||
+    rtn == FAST_IO ||
     !scsi_eh_tur(bdr_scmd)) {
 list_for_each_entry_safe(scmd, next,
  work_q, eh_entry) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1248,7 +1248,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int scsi_eh_target_reset(struct Scsi_Host *shost,
   "to target %d\n",
   current-&amp;gt;comm, id));
 rtn = scsi_try_target_reset(scmd);
-if (rtn != SUCCESS &amp;amp;&amp;amp; rtn != FAST_IO_FAIL)
+if (rtn != SUCCESS &amp;amp;&amp;amp; rtn != FAST_IO)
 SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Target reset"
   " failed target: "
   "%d\n",
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1259,7 +1259,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int scsi_eh_target_reset(struct Scsi_Host *shost,
 
 if (rtn == SUCCESS)
 list_move_tail(&amp;amp;scmd-&amp;gt;eh_entry, &amp;amp;check_list);
-else if (rtn == FAST_IO_FAIL)
+else if (rtn == FAST_IO)
 scsi_eh_finish_cmd(scmd, done_q);
 else
 /* push back on work queue for further processing */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1311,10 +1311,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int scsi_eh_bus_reset(struct Scsi_Host *shost,
   " %d\n", current-&amp;gt;comm,
   channel));
 rtn = scsi_try_bus_reset(chan_scmd);
-if (rtn == SUCCESS || rtn == FAST_IO_FAIL) {
+if (rtn == SUCCESS || rtn == FAST_IO) {
 list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
 if (channel == scmd_channel(scmd)) {
-if (rtn == FAST_IO_FAIL)
+if (rtn == FAST_IO)
 scsi_eh_finish_cmd(scmd,
    done_q);
 else
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1354,7 +1354,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int scsi_eh_host_reset(struct list_head *work_q,
 rtn = scsi_try_host_reset(scmd);
 if (rtn == SUCCESS) {
 list_splice_init(work_q, &amp;amp;check_list);
-} else if (rtn == FAST_IO_FAIL) {
+} else if (rtn == FAST_IO) {
 list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
 scsi_eh_finish_cmd(scmd, done_q);
 }
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index e106c27..7b29e00 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3301,7 +3301,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fc_scsi_scan_rport(struct work_struct *work)
  * rports which would lead to offlined SCSI devices.
  *
  * Returns: 0 if the fc_rport left the state FC_PORTSTATE_BLOCKED.
- *    FAST_IO_FAIL if the fast_io_fail_tmo fired, this should be
+ *    FAST_IO if the fast_io_fail_tmo fired, this should be
  *    passed back to scsi_eh.
  */
 int fc_block_scsi_eh(struct scsi_cmnd *cmnd)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3320,7 +3320,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int fc_block_scsi_eh(struct scsi_cmnd *cmnd)
 spin_unlock_irqrestore(shost-&amp;gt;host_lock, flags);
 
 if (rport-&amp;gt;flags &amp;amp; FC_RPORT_FAST_FAIL_TIMEDOUT)
-return FAST_IO_FAIL;
+return FAST_IO;
 
 return 0;
 }
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 133926b..8a88f45 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1528,8 +1528,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void iscsi_scan_session(struct work_struct *work)
  *
  * If the session is down this function will wait for the recovery
  * timer to fire or for the session to be logged back in. If the
- * recovery timer fires then FAST_IO_FAIL is returned. The caller
- * should pass this error value to the scsi eh.
+ * recovery timer fires then FAST_IO is returned. The caller should
+ * pass this error value to the scsi eh.
  */
 int iscsi_block_scsi_eh(struct scsi_cmnd *cmd)
 {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1541,7 +1541,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int iscsi_block_scsi_eh(struct scsi_cmnd *cmd)
 spin_lock_irqsave(&amp;amp;session-&amp;gt;lock, flags);
 while (session-&amp;gt;state != ISCSI_SESSION_LOGGED_IN) {
 if (session-&amp;gt;state == ISCSI_SESSION_FREE) {
-ret = FAST_IO_FAIL;
+ret = FAST_IO;
 break;
 }
 spin_unlock_irqrestore(&amp;amp;session-&amp;gt;lock, flags);
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 66216c1..3e12e1e 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -480,7 +480,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline int scsi_is_wlun(unsigned int lun)
 #define ADD_TO_MLQUEUE  0x2006
 #define TIMEOUT_ERROR   0x2007
 #define SCSI_RETURN_NOT_HANDLED   0x2008
-#define FAST_IO_FAIL0x2009
+#define FAST_IO         0x2009
 #define TARGET_ERROR    0x200A
 
 /*
&lt;/pre&gt;</description>
    <dc:creator>Ren Mingxin</dc:creator>
    <dc:date>2013-05-20T07:14:59</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82091">
    <title>CHECK.</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82091</link>
    <description>&lt;pre&gt;


Attention,

Important message from ADMIN- Please confirm your email address by
clicking this link:

http://feedbck.jimdo.com/

Webmaster

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo&amp;lt; at &amp;gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>Help Desk</dc:creator>
    <dc:date>2013-05-19T20:28:31</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82090">
    <title>Re: SCSI testing/USB devices are amazing</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82090</link>
    <description>&lt;pre&gt;
Hi,
If you are working in the WRITE SAME (WS) area, you could make
this addition: T10/Robert Elliott just added a NDOB bit
('no data-out buffer') to WS(16) and WS(32) in sbc3r35d.pdf .

Using it vastly simplifies my sg_write_same code but I don't
understand why NDOB=1,UNMAP=0 is disallowed.

Doug Gilbert


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo&amp;lt; at &amp;gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>Douglas Gilbert</dc:creator>
    <dc:date>2013-05-19T17:39:16</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82089">
    <title>[PATCH v2 5/5] scsi_debug: reduce duplication between prot_verify_read and prot_verify_write</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82089</link>
    <description>&lt;pre&gt;In order to reduce code duplication between prot_verify_read() and
prot_verify_write(), this moves common code into the new functions.

Signed-off-by: Akinobu Mita &amp;lt;akinobu.mita&amp;lt; at &amp;gt;gmail.com&amp;gt;
Cc: "James E.J. Bottomley" &amp;lt;JBottomley&amp;lt; at &amp;gt;parallels.com&amp;gt;
Cc: Douglas Gilbert &amp;lt;dgilbert&amp;lt; at &amp;gt;interlog.com&amp;gt;
Cc: "Martin K. Petersen" &amp;lt;martin.petersen&amp;lt; at &amp;gt;oracle.com&amp;gt;
Cc: linux-scsi&amp;lt; at &amp;gt;vger.kernel.org
---

* New patch from v2

 drivers/scsi/scsi_debug.c | 135 +++++++++++++++++++---------------------------
 1 file changed, 54 insertions(+), 81 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 152ead6..bd14e12 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1710,6 +1710,50 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int do_device_access(struct scsi_cmnd *scmd,
 return ret;
 }
 
+static u16 dif_compute_csum(const void *buf, int len)
+{
+u16 csum;
+
+switch (scsi_debug_guard) {
+case 1:
+csum = ip_compute_csum(buf, len);
+break;
+case 0:
+csum = cpu_to_be16(crc_t10dif(buf, len));
+break;
+default:
+BUG();
+}
+return csum;
+}
+
+static int dif_verify(struct sd_dif_tuple *sdt, u16 csum, sector_t sector,
+      u32 ei_lba)
+{
+if (sdt-&amp;gt;guard_tag != csum) {
+pr_err("%s: GUARD check failed on sector %lu rcvd 0x%04x, data 0x%04x\n",
+__func__,
+(unsigned long)sector,
+be16_to_cpu(sdt-&amp;gt;guard_tag),
+be16_to_cpu(csum));
+return 0x01;
+}
+if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION &amp;amp;&amp;amp;
+    be32_to_cpu(sdt-&amp;gt;ref_tag) != (sector &amp;amp; 0xffffffff)) {
+pr_err("%s: REF check failed on sector %lu\n",
+__func__, (unsigned long)sector);
+return 0x03;
+}
+if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &amp;amp;&amp;amp;
+    be32_to_cpu(sdt-&amp;gt;ref_tag) != ei_lba) {
+pr_err("%s: REF check failed on sector %lu\n",
+__func__, (unsigned long)sector);
+dif_errors++;
+return 0x03;
+}
+return 0;
+}
+
 static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec,
     unsigned int sectors, u32 ei_lba)
 {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1726,52 +1770,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec,
 
 for (i = 0 ; i &amp;lt; sectors ; i++) {
 u16 csum;
+int ret;
 
 if (sdt[i].app_tag == 0xffff)
 continue;
 
 sector = start_sec + i;
 
-switch (scsi_debug_guard) {
-case 1:
-csum = ip_compute_csum(fake_storep +
-       sector * scsi_debug_sector_size,
-       scsi_debug_sector_size);
-break;
-case 0:
-csum = crc_t10dif(fake_storep +
-  sector * scsi_debug_sector_size,
-  scsi_debug_sector_size);
-csum = cpu_to_be16(csum);
-break;
-default:
-BUG();
-}
+csum = dif_compute_csum(fake_storep +
+sector * scsi_debug_sector_size,
+scsi_debug_sector_size);
 
-if (sdt[i].guard_tag != csum) {
-printk(KERN_ERR "%s: GUARD check failed on sector %lu" \
-       " rcvd 0x%04x, data 0x%04x\n", __func__,
-       (unsigned long)sector,
-       be16_to_cpu(sdt[i].guard_tag),
-       be16_to_cpu(csum));
+ret = dif_verify(&amp;amp;sdt[i], csum, sector, ei_lba);
+if (ret) {
 dif_errors++;
-return 0x01;
-}
-
-if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION &amp;amp;&amp;amp;
-    be32_to_cpu(sdt[i].ref_tag) != (sector &amp;amp; 0xffffffff)) {
-printk(KERN_ERR "%s: REF check failed on sector %lu\n",
-       __func__, (unsigned long)sector);
-dif_errors++;
-return 0x03;
-}
-
-if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &amp;amp;&amp;amp;
-    be32_to_cpu(sdt[i].ref_tag) != ei_lba) {
-printk(KERN_ERR "%s: REF check failed on sector %lu\n",
-       __func__, (unsigned long)sector);
-dif_errors++;
-return 0x03;
+return ret;
 }
 
 ei_lba++;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1911,50 +1924,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
 
 sdt = paddr + ppage_offset;
 
-switch (scsi_debug_guard) {
-case 1:
-csum = ip_compute_csum(daddr,
-       scsi_debug_sector_size);
-break;
-case 0:
-csum = cpu_to_be16(crc_t10dif(daddr,
-      scsi_debug_sector_size));
-break;
-default:
-BUG();
-ret = 0;
-goto out;
-}
-
-if (sdt-&amp;gt;guard_tag != csum) {
-printk(KERN_ERR
-       "%s: GUARD check failed on sector %lu " \
-       "rcvd 0x%04x, calculated 0x%04x\n",
-       __func__, (unsigned long)sector,
-       be16_to_cpu(sdt-&amp;gt;guard_tag),
-       be16_to_cpu(csum));
-ret = 0x01;
-dump_sector(daddr, scsi_debug_sector_size);
-goto out;
-}
-
-if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION &amp;amp;&amp;amp;
-    be32_to_cpu(sdt-&amp;gt;ref_tag)
-    != (start_sec &amp;amp; 0xffffffff)) {
-printk(KERN_ERR
-       "%s: REF check failed on sector %lu\n",
-       __func__, (unsigned long)sector);
-ret = 0x03;
-dump_sector(daddr, scsi_debug_sector_size);
-goto out;
-}
+csum = dif_compute_csum(daddr, scsi_debug_sector_size);
 
-if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &amp;amp;&amp;amp;
-    be32_to_cpu(sdt-&amp;gt;ref_tag) != ei_lba) {
-printk(KERN_ERR
-       "%s: REF check failed on sector %lu\n",
-       __func__, (unsigned long)sector);
-ret = 0x03;
+ret = dif_verify(sdt, csum, start_sec, ei_lba);
+if (ret) {
 dump_sector(daddr, scsi_debug_sector_size);
 goto out;
 }
&lt;/pre&gt;</description>
    <dc:creator>Akinobu Mita</dc:creator>
    <dc:date>2013-05-19T13:42:09</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82088">
    <title>[PATCH v2 4/5] scsi_debug: simplify offset calculation for dif_storep</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82088</link>
    <description>&lt;pre&gt;dif_storep is declared as pointer to unsigned char type.  But it is
actually used to store vmalloced array of struct sd_dif_tuple.

This changes the type of dif_storep to the pointer to struct sd_dif_tuple.
It simplifies offset calculation for dif_storep and enables to remove
hardcoded size of struct sd_dif_tuple.

Signed-off-by: Akinobu Mita &amp;lt;akinobu.mita&amp;lt; at &amp;gt;gmail.com&amp;gt;
Cc: "James E.J. Bottomley" &amp;lt;JBottomley&amp;lt; at &amp;gt;parallels.com&amp;gt;
Cc: Douglas Gilbert &amp;lt;dgilbert&amp;lt; at &amp;gt;interlog.com&amp;gt;
Cc: "Martin K. Petersen" &amp;lt;martin.petersen&amp;lt; at &amp;gt;oracle.com&amp;gt;
Cc: linux-scsi&amp;lt; at &amp;gt;vger.kernel.org
Acked-by: Douglas Gilbert &amp;lt;dgilbert&amp;lt; at &amp;gt;interlog.com&amp;gt;
---

* No changes from v1

 drivers/scsi/scsi_debug.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 631e9ab..152ead6 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -258,7 +258,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct sdebug_queued_cmd {
 static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE];
 
 static unsigned char * fake_storep;/* ramdisk storage */
-static unsigned char *dif_storep;/* protection info */
+static struct sd_dif_tuple *dif_storep;/* protection info */
 static void *map_storep;/* provisioning map */
 
 static unsigned long map_size;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -277,11 +277,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static char sdebug_proc_name[] = "scsi_debug";
 
 static struct bus_type pseudo_lld_bus;
 
-static inline sector_t dif_offset(sector_t sector)
-{
-return sector &amp;lt;&amp;lt; 3;
-}
-
 static struct device_driver sdebug_driverfs_driver = {
 .name = sdebug_proc_name,
 .bus= &amp;amp;pseudo_lld_bus,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1727,7 +1722,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec,
 
 start_sec = do_div(tmp_sec, sdebug_store_sectors);
 
-sdt = (struct sd_dif_tuple *)(dif_storep + dif_offset(start_sec));
+sdt = dif_storep + start_sec;
 
 for (i = 0 ; i &amp;lt; sectors ; i++) {
 u16 csum;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1782,16 +1777,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec,
 ei_lba++;
 }
 
-resid = sectors * 8; /* Bytes of protection data to copy into sgl */
+/* Bytes of protection data to copy into sgl */
+resid = sectors * sizeof(*dif_storep);
 sector = start_sec;
 
 scsi_for_each_prot_sg(SCpnt, psgl, scsi_prot_sg_count(SCpnt), i) {
 int len = min(psgl-&amp;gt;length, resid);
 
 paddr = kmap_atomic(sg_page(psgl)) + psgl-&amp;gt;offset;
-memcpy(paddr, dif_storep + dif_offset(sector), len);
+memcpy(paddr, dif_storep + sector, len);
 
-sector += len &amp;gt;&amp;gt; 3;
+sector += len / sizeof(*dif_storep);
 if (sector &amp;gt;= sdebug_store_sectors) {
 /* Force wrap */
 tmp_sec = sector;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1968,7 +1964,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
  * correctness we need to verify each sector
  * before writing it to "stable" storage
  */
-memcpy(dif_storep + dif_offset(sector), sdt, 8);
+memcpy(dif_storep + sector, sdt, sizeof(*sdt));
 
 sector++;
 
&lt;/pre&gt;</description>
    <dc:creator>Akinobu Mita</dc:creator>
    <dc:date>2013-05-19T13:42:08</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82087">
    <title>[PATCH v2 3/5] scsi_debug: fix NULL pointer dereference with parameters dif=0 dix=1</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82087</link>
    <description>&lt;pre&gt;The protection info dif_storep is allocated only when parameter dif is
not zero.  But it will be accessed when reading or writing to the storage
installed with parameter dix is not zero.

So kernel crashes if scsi_debug module is loaded with parameters dix=1 and
dif=0.

This fixes it by making dif_storep available if parameter dix is not zero
instead of checking if parameter dif is not zero.

Signed-off-by: Akinobu Mita &amp;lt;akinobu.mita&amp;lt; at &amp;gt;gmail.com&amp;gt;
Cc: "James E.J. Bottomley" &amp;lt;JBottomley&amp;lt; at &amp;gt;parallels.com&amp;gt;
Cc: Douglas Gilbert &amp;lt;dgilbert&amp;lt; at &amp;gt;interlog.com&amp;gt;
Cc: "Martin K. Petersen" &amp;lt;martin.petersen&amp;lt; at &amp;gt;oracle.com&amp;gt;
Cc: linux-scsi&amp;lt; at &amp;gt;vger.kernel.org
Acked-by: Douglas Gilbert &amp;lt;dgilbert&amp;lt; at &amp;gt;interlog.com&amp;gt;
Acked-by: "Martin K. Petersen" &amp;lt;martin.petersen&amp;lt; at &amp;gt;oracle.com&amp;gt;
---

* No changes from v1

 drivers/scsi/scsi_debug.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 0a428b6..631e9ab 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3373,7 +3373,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int __init scsi_debug_init(void)
 if (scsi_debug_num_parts &amp;gt; 0)
 sdebug_build_parts(fake_storep, sz);
 
-if (scsi_debug_dif) {
+if (scsi_debug_dix) {
 int dif_size;
 
 dif_size = sdebug_store_sectors * sizeof(struct sd_dif_tuple);
&lt;/pre&gt;</description>
    <dc:creator>Akinobu Mita</dc:creator>
    <dc:date>2013-05-19T13:42:07</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82086">
    <title>[PATCH v2 2/5] scsi_debug: fix incorrectly nested kmap_atomic()</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82086</link>
    <description>&lt;pre&gt;In the function prot_verify_write(), kmap_atomic()/kunmap_atomic() for
data page and kmap_atomic()/kunmap_atomic() for protection information
page are not nested each other.

It worked perfectly before commit 3e4d3af501cccdc8a8cca41bdbe57d54ad7e7e73
("mm: stack based kmap_atomic()").  Because the kmap_atomic slot KM_IRQ0
was used for data page and the slot KM_IRQ1 was used for protection page.

But KM_types are gone and kmap_atomic() is using stack based implementation.
So two different kmap_atomic() usages must be strictly nested now.

This change ensures kmap_atomic() usage is strictly nested.

Signed-off-by: Akinobu Mita &amp;lt;akinobu.mita&amp;lt; at &amp;gt;gmail.com&amp;gt;
Cc: "James E.J. Bottomley" &amp;lt;JBottomley&amp;lt; at &amp;gt;parallels.com&amp;gt;
Cc: Douglas Gilbert &amp;lt;dgilbert&amp;lt; at &amp;gt;interlog.com&amp;gt;
Cc: "Martin K. Petersen" &amp;lt;martin.petersen&amp;lt; at &amp;gt;oracle.com&amp;gt;
Cc: linux-scsi&amp;lt; at &amp;gt;vger.kernel.org
Acked-by: Douglas Gilbert &amp;lt;dgilbert&amp;lt; at &amp;gt;interlog.com&amp;gt;
---

* New patch from v2
- Splitted from the patch "fix data integrity support on highmem machine" in v1

 drivers/scsi/scsi_debug.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index caf6a94..0a428b6 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1891,12 +1891,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
 BUG_ON(scsi_sg_count(SCpnt) == 0);
 BUG_ON(scsi_prot_sg_count(SCpnt) == 0);
 
-paddr = kmap_atomic(sg_page(psgl)) + psgl-&amp;gt;offset;
 ppage_offset = 0;
 
 /* For each data page */
 scsi_for_each_sg(SCpnt, dsgl, scsi_sg_count(SCpnt), i) {
 daddr = kmap_atomic(sg_page(dsgl)) + dsgl-&amp;gt;offset;
+paddr = kmap_atomic(sg_page(psgl)) + psgl-&amp;gt;offset;
 
 /* For each sector-sized chunk in data page */
 for (j = 0 ; j &amp;lt; dsgl-&amp;gt;length ; j += scsi_debug_sector_size) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1981,19 +1981,18 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
 ppage_offset += sizeof(struct sd_dif_tuple);
 }
 
+kunmap_atomic(paddr);
 kunmap_atomic(daddr - dsgl-&amp;gt;length);
 }
 
-kunmap_atomic(paddr);
-
 dix_writes++;
 
 return 0;
 
 out:
 dif_errors++;
-kunmap_atomic(daddr);
 kunmap_atomic(paddr);
+kunmap_atomic(daddr);
 return ret;
 }
 
&lt;/pre&gt;</description>
    <dc:creator>Akinobu Mita</dc:creator>
    <dc:date>2013-05-19T13:42:06</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82085">
    <title>[PATCH v2 1/5] scsi_debug: fix invalid address passed to kunmap_atomic()</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82085</link>
    <description>&lt;pre&gt;In the function prot_verify_write(), the kmap address 'daddr' is
incremented in the loop for each data page.  Finally 'daddr' reaches
the next page boundary in the end of the loop, and the invalid address
is passed to kunmap_atomic().

Fix it by passing original value to kunmap_atomic().

Signed-off-by: Akinobu Mita &amp;lt;akinobu.mita&amp;lt; at &amp;gt;gmail.com&amp;gt;
Cc: "James E.J. Bottomley" &amp;lt;JBottomley&amp;lt; at &amp;gt;parallels.com&amp;gt;
Cc: Douglas Gilbert &amp;lt;dgilbert&amp;lt; at &amp;gt;interlog.com&amp;gt;
Cc: "Martin K. Petersen" &amp;lt;martin.petersen&amp;lt; at &amp;gt;oracle.com&amp;gt;
Cc: linux-scsi&amp;lt; at &amp;gt;vger.kernel.org
Acked-by: Douglas Gilbert &amp;lt;dgilbert&amp;lt; at &amp;gt;interlog.com&amp;gt;
---

* New patch from v2
- Splitted from the patch "fix data integrity support on highmem machine" in v1

 drivers/scsi/scsi_debug.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 0a537a0..caf6a94 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1981,7 +1981,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
 ppage_offset += sizeof(struct sd_dif_tuple);
 }
 
-kunmap_atomic(daddr);
+kunmap_atomic(daddr - dsgl-&amp;gt;length);
 }
 
 kunmap_atomic(paddr);
&lt;/pre&gt;</description>
    <dc:creator>Akinobu Mita</dc:creator>
    <dc:date>2013-05-19T13:42:05</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82084">
    <title>[PATCH v2 0/5] scsi_debug: bug fixes and cleanups for data integrity support</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82084</link>
    <description>&lt;pre&gt;This patch set includes bug fixes which I hit when I was tried testing
the data integrity support in scsi_debug on x86_32.

And it also includes cleanups which helps increasing readability and
further bug fixing in data integrity support.

* Changes from v1
- Split the patch "fix data integrity support on highmem machine" into
  two separate patches.
- Add new cleanup patch "reduce duplication between prot_verify_read and
  prot_verify_write".

Cc: "James E.J. Bottomley" &amp;lt;JBottomley&amp;lt; at &amp;gt;parallels.com&amp;gt;
Cc: Douglas Gilbert &amp;lt;dgilbert&amp;lt; at &amp;gt;interlog.com&amp;gt;
Cc: "Martin K. Petersen" &amp;lt;martin.petersen&amp;lt; at &amp;gt;oracle.com&amp;gt;
Cc: linux-scsi&amp;lt; at &amp;gt;vger.kernel.org

Akinobu Mita (5):
  scsi_debug: fix invalid address passed to kunmap_atomic()
  scsi_debug: fix incorrectly nested kmap_atomic()
  scsi_debug: fix NULL pointer dereference with parameters dif=0 dix=1
  scsi_debug: simplify offset calculation for dif_storep
  scsi_debug: reduce duplication between prot_verify_read and
    prot_verify_write

 drivers/scsi/scsi_debug.c | 164 +++++++++++++++++++---------------------------
 1 file changed, 66 insertions(+), 98 deletions(-)

&lt;/pre&gt;</description>
    <dc:creator>Akinobu Mita</dc:creator>
    <dc:date>2013-05-19T13:42:04</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82083">
    <title>[PATCH 8/8] scsi: ufs: Fix the response UPIU length setting</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82083</link>
    <description>&lt;pre&gt;From: Sujit Reddy Thumma &amp;lt;sthumma&amp;lt; at &amp;gt;codeaurora.org&amp;gt;

The response UPIU length should be in DWORD and not in bytes.

Signed-off-by: Maya Erez &amp;lt;merez&amp;lt; at &amp;gt;codeaurora.org&amp;gt;
Signed-off-by: Sujit Reddy Thumma &amp;lt;sthumma&amp;lt; at &amp;gt;codeaurora.org&amp;gt;
Signed-off-by: Santosh Y &amp;lt;santoshsy&amp;lt; at &amp;gt;gmail.com&amp;gt;

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 18dead4..e9dba33 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1159,7 +1159,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_host_memory_configure(struct ufs_hba *hba)
 utrdlp[i].prd_table_offset =
 cpu_to_le16((prdt_offset &amp;gt;&amp;gt; 2));
 utrdlp[i].response_upiu_length =
-cpu_to_le16(ALIGNED_UPIU_SIZE);
+cpu_to_le16(ALIGNED_UPIU_SIZE &amp;gt;&amp;gt; 2);
 
 hba-&amp;gt;lrb[i].utr_descriptor_ptr = (utrdlp + i);
 hba-&amp;gt;lrb[i].ucd_req_ptr =
&lt;/pre&gt;</description>
    <dc:creator>Santosh Y</dc:creator>
    <dc:date>2013-05-19T08:21:43</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82082">
    <title>[PATCH 7/8] scsi: ufs: Set fDeviceInit flag to initiate device initialization</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82082</link>
    <description>&lt;pre&gt;From: Dolev Raviv &amp;lt;draviv&amp;lt; at &amp;gt;codeaurora.org&amp;gt;

Allow UFS device to complete its initialization and accept
SCSI commands by setting fDeviceInit flag. The device may take
time for this operation and hence the host should poll until
fDeviceInit flag is toggled to zero. This step is mandated by
UFS device specification for device initialization completion.

Signed-off-by: Dolev Raviv &amp;lt;draviv&amp;lt; at &amp;gt;codeaurora.org&amp;gt;
Signed-off-by: Sujit Reddy Thumma &amp;lt;sthumma&amp;lt; at &amp;gt;codeaurora.org&amp;gt;
Signed-off-by: Santosh Y &amp;lt;santoshsy&amp;lt; at &amp;gt;gmail.com&amp;gt;

diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 086ff03..742363d 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -107,8 +107,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; enum {
 UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST = 0x81,
 };
 
+/* Flag idn for Query Requests*/
+enum flag_idn {
+QUERY_FLAG_IDN_FDEVICEINIT = 0x01,
+};
+
 /* UTP QUERY Transaction Specific Fields OpCode */
-enum {
+enum query_opcode {
 UPIU_QUERY_OPCODE_NOP= 0x0,
 UPIU_QUERY_OPCODE_READ_DESC= 0x1,
 UPIU_QUERY_OPCODE_WRITE_DESC= 0x2,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -208,6 +213,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct utp_upiu_query {
 u32 reserved[2];
 };
 
+/* Expose the flag value from utp_upiu_query.value */
+#define MASK_QUERY_UPIU_FLAG_LOC 0xFF
+
 /**
  * struct utp_upiu_req - general upiu request structure
  * &amp;lt; at &amp;gt;header:UPIU header structure DW-0 to DW-2
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index daed7387..18dead4 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -50,6 +50,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 /* Reserved tag for internal commands */
 #define INTERNAL_CMD_TAG   0
 
+/* Query request standart retries */
+#define QUERY_REQ_RETRIES 10
+/* Query request standart timeout  in seconds */
+#define QUERY_REQ_TIMEOUT 5
+/* Send Query Requst with default parameters */
+#define send_query_request(ARG1, ARG2, ARG3, ARG4)\
+ufshcd_query_request(ARG1, ARG2, ARG3, ARG4,\
+QUERY_REQ_TIMEOUT, QUERY_REQ_RETRIES)
+
 enum {
 UFSHCD_MAX_CHANNEL= 0,
 UFSHCD_MAX_ID= 1,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -862,6 +871,164 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out:
 }
 
 /**
+ *  ufshcd_query_request() - Entry point for issuing query request to a
+ *  ufs device.
+ *  &amp;lt; at &amp;gt;hba: ufs driver context
+ *  &amp;lt; at &amp;gt;query: params for query request
+ *  &amp;lt; at &amp;gt;descriptor: buffer for sending/receiving descriptor
+ *  &amp;lt; at &amp;gt;response: pointer to a buffer that will contain the response code and
+ *           response upiu
+ *  &amp;lt; at &amp;gt;timeout: time limit for the command in seconds
+ *  &amp;lt; at &amp;gt;retries: number of times to try executing the command
+ *
+ *  The query request is submitted to the same request queue as the rest of
+ *  the scsi commands passed to the UFS controller. In order to use this
+ *  queue, we need to receive a tag, same as all other commands. The tags
+ *  are issued from the block layer. To simulate a request from the block
+ *  layer, we use the same interface as the SCSI layer does when it issues
+ *  commands not generated by users. To distinguish a query request from
+ *  the SCSI commands, we use a vendor specific unused SCSI command
+ *  op-code. This op-code is not part of the SCSI command subset used in
+ *  UFS. In such way it is easy to check the command in the driver and
+ *  handle it appropriately.
+ *
+ *  All necessary fields for issuing a query and receiving its response are
+ *  stored in the UFS hba struct. We can use this method since we know
+ *  there is only one active query request at all times.
+ *
+ *  The request that will pass to the device is stored in "query" argument
+ *  passed to this function, while the "response" argument (which is output
+ *  field) will hold the query response from the device along with the
+ *  response code.
+ */
+int ufshcd_query_request(struct ufs_hba *hba,
+struct ufs_query_req *query,
+u8 *descriptor,
+struct ufs_query_res *response,
+int timeout,
+int retries)
+{
+struct scsi_device *sdev;
+u8 cmd[UFS_QUERY_CMD_SIZE] = {0};
+int result;
+bool sdev_lookup = true;
+
+BUG_ON(!hba);
+if (!query || !response) {
+dev_err(hba-&amp;gt;dev,
+"%s: NULL pointer hba = %p, query = %p response = %p\n",
+__func__, hba, query, response);
+return -EINVAL;
+}
+
+/*
+ * A SCSI command structure is composed from opcode at the
+ * begining and 0 at the end.
+ */
+cmd[0] = UFS_QUERY_RESERVED_SCSI_CMD;
+
+/* extracting the SCSI Device */
+sdev = scsi_device_lookup(hba-&amp;gt;host, 0, 0, 0);
+if (!sdev) {
+/**
+ * There are some Query Requests that are sent during device
+ * initialization, this happens before the scsi device was
+ * initialized. If there is no scsi device, we generate a
+ * temporary device to allow the Query Request flow.
+ */
+sdev_lookup = false;
+sdev = scsi_get_host_dev(hba-&amp;gt;host);
+}
+
+if (!sdev) {
+dev_err(hba-&amp;gt;dev, "%s: Could not fetch scsi device\n",
+__func__);
+return -ENODEV;
+}
+
+mutex_lock(&amp;amp;hba-&amp;gt;query.lock_ufs_query);
+hba-&amp;gt;query.request = query;
+hba-&amp;gt;query.descriptor = descriptor;
+hba-&amp;gt;query.response = response;
+
+/* wait until request is completed */
+result = scsi_execute(sdev, cmd, DMA_NONE, NULL, 0, NULL,
+timeout, retries, 0, NULL);
+if (result) {
+dev_err(hba-&amp;gt;dev,
+"%s: Query with opcode 0x%x, failed with result %d\n",
+__func__, query-&amp;gt;upiu_req.opcode, result);
+result = -EIO;
+}
+
+hba-&amp;gt;query.request = NULL;
+hba-&amp;gt;query.descriptor = NULL;
+hba-&amp;gt;query.response = NULL;
+mutex_unlock(&amp;amp;hba-&amp;gt;query.lock_ufs_query);
+
+/* Releasing scsi device resource */
+if (sdev_lookup)
+scsi_device_put(sdev);
+else
+scsi_free_host_dev(sdev);
+
+return result;
+}
+
+/**
+ * ufshcd_query_flag() - Helper function for composing flag query requests
+ * hba: per-adapter instance
+ * query_opcode: flag query to perform
+ * idn: flag idn to access
+ * flag_res: the flag value after the query request completes
+ *
+ * Returns 0 for success, non-zero in case of failure
+ */
+int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
+enum flag_idn idn, bool *flag_res)
+{
+struct ufs_query_req query = {0};
+struct ufs_query_res response = {0};
+int err;
+
+switch (opcode) {
+case UPIU_QUERY_OPCODE_SET_FLAG:
+case UPIU_QUERY_OPCODE_CLEAR_FLAG:
+case UPIU_QUERY_OPCODE_TOGGLE_FLAG:
+query.query_func = UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST;
+break;
+case UPIU_QUERY_OPCODE_READ_FLAG:
+query.query_func = UPIU_QUERY_FUNC_STANDARD_READ_REQUEST;
+break;
+default:
+dev_err(hba-&amp;gt;dev,
+"%s: Expected query flag opcode but got = %d\n",
+__func__, opcode);
+err = -EINVAL;
+goto out;
+}
+query.upiu_req.opcode = opcode;
+query.upiu_req.idn = idn;
+
+/* Send query request */
+err = send_query_request(hba, &amp;amp;query, NULL, &amp;amp;response);
+
+if (err) {
+dev_err(hba-&amp;gt;dev,
+"%s: Sending flag query for idn %d failed, err = %d\n",
+__func__, idn, err);
+goto out;
+}
+
+if (flag_res)
+*flag_res = (response.upiu_res.value &amp;amp;
+MASK_QUERY_UPIU_FLAG_LOC) &amp;amp; 0x1;
+
+out:
+return err;
+}
+
+/**
  * ufshcd_memory_alloc - allocate memory for host memory space data structures
  * &amp;lt; at &amp;gt;hba: per adapter instance
  *
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1128,6 +1295,44 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out:
 }
 
 /**
+ * ufshcd_validate_device_init() - checks device readines
+ * hba: per-adapter instance
+ *
+ * Set fDeviceInit flag, than, query the flag untill the device clears the
+ * flag.
+ */
+static int ufshcd_validate_device_init(struct ufs_hba *hba)
+{
+int i, err;
+bool flag_res = 0;
+
+err = ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_SET_FLAG,
+QUERY_FLAG_IDN_FDEVICEINIT, &amp;amp;flag_res);
+if (err) {
+dev_err(hba-&amp;gt;dev,
+"%s setting fDeviceInit flag failed with error %d\n",
+__func__, err);
+goto out;
+}
+
+for (i = 0; i &amp;lt; QUERY_REQ_RETRIES &amp;amp;&amp;amp; !err &amp;amp;&amp;amp; flag_res; i++) {
+err = ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_READ_FLAG,
+QUERY_FLAG_IDN_FDEVICEINIT, &amp;amp;flag_res);
+}
+if (err)
+dev_err(hba-&amp;gt;dev,
+"%s reading fDeviceInit flag failed with error %d\n",
+__func__, err);
+else if (flag_res)
+dev_err(hba-&amp;gt;dev,
+"%s fDeviceInit was not cleared by the device\n",
+__func__);
+
+out:
+return err;
+}
+
+/**
  * ufshcd_make_hba_operational - Make UFS controller operational
  * &amp;lt; at &amp;gt;hba: per adapter instance
  *
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1950,6 +2155,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_async_scan(void *data, async_cookie_t cookie)
 if (ret)
 goto out;
 
+ret = ufshcd_validate_device_init(hba);
+if (ret)
+goto out;
+
 scsi_scan_host(hba-&amp;gt;host);
 out:
 return;
&lt;/pre&gt;</description>
    <dc:creator>Santosh Y</dc:creator>
    <dc:date>2013-05-19T08:21:42</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82081">
    <title>[PATCH 6/8] scsi: ufs: Add support for sending NOP OUT UPIU</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82081</link>
    <description>&lt;pre&gt;From: Dolev Raviv &amp;lt;draviv&amp;lt; at &amp;gt;codeaurora.org&amp;gt;

As part of device initialization sequence, sending NOP OUT UPIU and
waiting for NOP IN UPIU response is mandatory. This confirms that the
device UFS Transport (UTP) layer is functional and the host can configure
the device with further commands. Add support for sending NOP OUT UPIU to
check the device connection path and test whether the UTP layer on the
device side is functional during initialization.

Signed-off-by: Sujit Reddy Thumma &amp;lt;sthumma&amp;lt; at &amp;gt;codeaurora.org&amp;gt;
Tested-by: Dolev Raviv &amp;lt;draviv&amp;lt; at &amp;gt;codeaurora.org&amp;gt;
Signed-off-by: Santosh Y &amp;lt;santoshsy&amp;lt; at &amp;gt;gmail.com&amp;gt;

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 0c570c0..daed7387 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -43,6 +43,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 /* UIC command timeout, unit: ms */
 #define UIC_CMD_TIMEOUT500
 
+/* NOP OUT retries waiting for NOP IN response */
+#define NOP_OUT_RETRIES    10
+/* Timeout after 30 msecs if NOP OUT hangs without response */
+#define NOP_OUT_TIMEOUT    30 /* msecs */
+/* Reserved tag for internal commands */
+#define INTERNAL_CMD_TAG   0
+
 enum {
 UFSHCD_MAX_CHANNEL= 0,
 UFSHCD_MAX_ID= 1,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -71,6 +78,39 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; enum {
 INT_AGGR_CONFIG,
 };
 
+/*
+ * ufshcd_wait_for_register - wait for register value to change
+ * &amp;lt; at &amp;gt;hba - per-adapter interface
+ * &amp;lt; at &amp;gt;reg - mmio register offset
+ * &amp;lt; at &amp;gt;mask - mask to apply to read register value
+ * &amp;lt; at &amp;gt;val - wait condition
+ * &amp;lt; at &amp;gt;interval_us - polling interval in microsecs
+ * &amp;lt; at &amp;gt;timeout_ms - timeout in millisecs
+ *
+ * Returns final register value after iteration
+ */
+static u32 ufshcd_wait_for_register(struct ufs_hba *hba, u32 reg, u32 mask,
+u32 val, unsigned long interval_us, unsigned long timeout_ms)
+{
+u32 tmp;
+ktime_t start;
+unsigned long diff;
+
+tmp = ufshcd_readl(hba, reg);
+
+start = ktime_get();
+while ((tmp &amp;amp; mask) == val) {
+/* wakeup within 50us of expiry */
+usleep_range(interval_us, interval_us + 50);
+tmp = ufshcd_readl(hba, reg);
+diff = ktime_to_ms(ktime_sub(ktime_get(), start));
+if (diff &amp;gt; timeout_ms)
+break;
+}
+
+return tmp;
+}
+
 /**
  * ufshcd_get_intr_mask - Get the interrupt bit mask
  * &amp;lt; at &amp;gt;hba - Pointer to adapter instance
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -612,7 +652,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_prepare_req_desc(struct ufshcd_lrb *lrbp, u32 *upiu_flags)
 {
 struct utp_transfer_req_desc *req_desc = lrbp-&amp;gt;utr_descriptor_ptr;
 enum dma_data_direction cmd_dir =
-lrbp-&amp;gt;cmd-&amp;gt;sc_data_direction;
+lrbp-&amp;gt;cmd ? lrbp-&amp;gt;cmd-&amp;gt;sc_data_direction : DMA_NONE;
 u32 data_direction;
 u32 dword_0;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -629,6 +669,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_prepare_req_desc(struct ufshcd_lrb *lrbp, u32 *upiu_flags)
 
 dword_0 = data_direction | (lrbp-&amp;gt;command_type
 &amp;lt;&amp;lt; UPIU_COMMAND_TYPE_OFFSET);
+if (lrbp-&amp;gt;intr_cmd)
+dword_0 |= UTP_REQ_DESC_INT_CMD;
 
 /* Transfer request descriptor header fields */
 req_desc-&amp;gt;header.dword_0 = cpu_to_le32(dword_0);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -717,6 +759,18 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_prepare_utp_query_req_upiu(struct ufs_hba *hba,
 
 }
 
+static inline void ufshcd_prepare_utp_nop_upiu(struct ufshcd_lrb *lrbp)
+{
+struct utp_upiu_req *ucd_req_ptr = lrbp-&amp;gt;ucd_req_ptr;
+
+memset(ucd_req_ptr, 0, sizeof(struct utp_upiu_req));
+
+/* command descriptor fields */
+ucd_req_ptr-&amp;gt;header.dword_0 =
+UPIU_HEADER_DWORD(
+UPIU_TRANSACTION_NOP_OUT, 0, 0, lrbp-&amp;gt;task_tag);
+}
+
 /**
  * ufshcd_compose_upiu - form UFS Protocol Information Unit(UPIU)
  * &amp;lt; at &amp;gt;hba - UFS hba
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -731,11 +785,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ufshcd_compose_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
 case UTP_CMD_TYPE_SCSI:
 case UTP_CMD_TYPE_DEV_MANAGE:
 ufshcd_prepare_req_desc(lrbp, &amp;amp;upiu_flags);
-if (lrbp-&amp;gt;command_type == UTP_CMD_TYPE_SCSI)
+if (lrbp-&amp;gt;cmd &amp;amp;&amp;amp; lrbp-&amp;gt;command_type == UTP_CMD_TYPE_SCSI)
 ufshcd_prepare_utp_scsi_cmd_upiu(lrbp, upiu_flags);
-else
+else if (lrbp-&amp;gt;cmd &amp;amp;&amp;amp; ufshcd_is_query_req(lrbp))
 ufshcd_prepare_utp_query_req_upiu(hba, lrbp,
 upiu_flags);
+else if (!lrbp-&amp;gt;cmd)
+ufshcd_prepare_utp_nop_upiu(lrbp);
 break;
 case UTP_CMD_TYPE_UFS:
 /* For UFS native command implementation */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -784,6 +840,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 lrbp-&amp;gt;sense_buffer = cmd-&amp;gt;sense_buffer;
 lrbp-&amp;gt;task_tag = tag;
 lrbp-&amp;gt;lun = cmd-&amp;gt;device-&amp;gt;lun;
+lrbp-&amp;gt;intr_cmd = false;
 
 if (ufshcd_is_query_req(lrbp))
 lrbp-&amp;gt;command_type = UTP_CMD_TYPE_DEV_MANAGE;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -972,6 +1029,104 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ufshcd_dme_link_startup(struct ufs_hba *hba)
 return ret;
 }
 
+static int
+ufshcd_compose_nop_out_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
+{
+lrbp-&amp;gt;cmd = NULL;
+lrbp-&amp;gt;sense_bufflen = 0;
+lrbp-&amp;gt;sense_buffer = NULL;
+lrbp-&amp;gt;task_tag = INTERNAL_CMD_TAG;
+lrbp-&amp;gt;lun = 0; /* NOP OUT is not specific to any LUN */
+lrbp-&amp;gt;command_type = UTP_CMD_TYPE_DEV_MANAGE;
+lrbp-&amp;gt;intr_cmd = true; /* No interrupt aggregation */
+
+return ufshcd_compose_upiu(hba, lrbp);
+}
+
+static int ufshcd_wait_for_nop_cmd(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
+{
+int err = 0;
+unsigned long timeout;
+unsigned long flags;
+
+timeout = wait_for_completion_timeout(
+lrbp-&amp;gt;completion, msecs_to_jiffies(NOP_OUT_TIMEOUT));
+
+spin_lock_irqsave(hba-&amp;gt;host-&amp;gt;host_lock, flags);
+lrbp-&amp;gt;completion = NULL;
+if (timeout)
+err = ufshcd_get_tr_ocs(lrbp);
+else
+err = -ETIMEDOUT;
+spin_unlock_irqrestore(hba-&amp;gt;host-&amp;gt;host_lock, flags);
+
+return err;
+}
+
+/**
+ * ufshcd_validate_dev_connection() - Check device connection status
+ * &amp;lt; at &amp;gt;hba: per-adapter instance
+ *
+ * Send NOP OUT UPIU and wait for NOP IN response to check whether the
+ * device Transport Protocol (UTP) layer is ready after a reset.
+ * If the UTP layer at the device side is not initialized, it may
+ * not respond with NOP IN UPIU within timeout of %NOP_OUT_TIMEOUT
+ * and we retry sending NOP OUT for %NOP_OUT_RETRIES iterations.
+ */
+static int ufshcd_validate_dev_connection(struct ufs_hba *hba)
+{
+int err;
+struct ufshcd_lrb *lrbp;
+unsigned long flags;
+struct completion wait;
+int retries = NOP_OUT_RETRIES;
+
+retry:
+init_completion(&amp;amp;wait);
+
+spin_lock_irqsave(hba-&amp;gt;host-&amp;gt;host_lock, flags);
+lrbp = &amp;amp;hba-&amp;gt;lrb[INTERNAL_CMD_TAG];
+err = ufshcd_compose_nop_out_upiu(hba, lrbp);
+if (unlikely(err)) {
+spin_unlock_irqrestore(hba-&amp;gt;host-&amp;gt;host_lock, flags);
+goto out;
+}
+
+lrbp-&amp;gt;completion = &amp;amp;wait;
+ufshcd_send_command(hba, INTERNAL_CMD_TAG);
+spin_unlock_irqrestore(hba-&amp;gt;host-&amp;gt;host_lock, flags);
+
+err = ufshcd_wait_for_nop_cmd(hba, lrbp);
+
+if (err == -ETIMEDOUT) {
+u32 reg;
+u32 mask = 1 &amp;lt;&amp;lt; INTERNAL_CMD_TAG;
+
+/* clear outstanding transaction before retry */
+spin_lock_irqsave(hba-&amp;gt;host-&amp;gt;host_lock, flags);
+ufshcd_utrl_clear(hba, INTERNAL_CMD_TAG);
+__clear_bit(INTERNAL_CMD_TAG, &amp;amp;hba-&amp;gt;outstanding_reqs);
+spin_unlock_irqrestore(hba-&amp;gt;host-&amp;gt;host_lock, flags);
+
+/* poll for max. 1 sec to clear door bell register by h/w */
+reg = ufshcd_wait_for_register(hba,
+REG_UTP_TRANSFER_REQ_DOOR_BELL,
+mask, mask, 1000, 1000);
+if ((reg &amp;amp; mask) == mask)
+retries = 0;
+}
+
+if (err &amp;amp;&amp;amp; retries--) {
+dev_dbg(hba-&amp;gt;dev, "%s: error %d retrying\n", __func__, err);
+goto retry;
+}
+
+out:
+if (err)
+dev_err(hba-&amp;gt;dev, "%s: NOP OUT failed %d\n", __func__, err);
+return err;
+}
+
 /**
  * ufshcd_make_hba_operational - Make UFS controller operational
  * &amp;lt; at &amp;gt;hba: per adapter instance
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1438,6 +1593,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_uic_cmd_compl(struct ufs_hba *hba)
 }
 }
 
+/*
+ * ufshcd_is_nop_out_upiu() - check if the command is NOP OUT UPIU
+ * &amp;lt; at &amp;gt;lrbp: pointer to logical reference block
+ */
+static inline bool ufshcd_is_nop_out_upiu(struct ufshcd_lrb *lrbp)
+{
+return (be32_to_cpu(lrbp-&amp;gt;ucd_req_ptr-&amp;gt;header.dword_0) &amp;gt;&amp;gt; 24) ==
+UPIU_TRANSACTION_NOP_OUT;
+}
+
 /**
  * ufshcd_transfer_req_compl - handle SCSI and query command completion
  * &amp;lt; at &amp;gt;hba: per adapter instance
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1449,6 +1614,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_transfer_req_compl(struct ufs_hba *hba)
 u32 tr_doorbell;
 int result;
 int index;
+bool int_aggr_reset = true;
 
 lrb = hba-&amp;gt;lrb;
 tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1456,17 +1622,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_transfer_req_compl(struct ufs_hba *hba)
 
 for (index = 0; index &amp;lt; hba-&amp;gt;nutrs; index++) {
 if (test_bit(index, &amp;amp;completed_reqs)) {
-
-result = ufshcd_transfer_rsp_status(hba, &amp;amp;lrb[index]);
-
 if (lrb[index].cmd) {
+result = ufshcd_transfer_rsp_status(
+hba, &amp;amp;lrb[index]);
 scsi_dma_unmap(lrb[index].cmd);
 lrb[index].cmd-&amp;gt;result = result;
 lrb[index].cmd-&amp;gt;scsi_done(lrb[index].cmd);
 
 /* Mark completed command as NULL in LRB */
 lrb[index].cmd = NULL;
+} else if (ufshcd_is_nop_out_upiu(&amp;amp;lrb[index])) {
+if (lrb[index].completion)
+complete(lrb[index].completion);
 }
+/* Don't reset counters for interrupt cmd */
+int_aggr_reset = lrb[index].intr_cmd ? false : true;
 } /* end of if */
 } /* end of for */
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1474,7 +1644,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_transfer_req_compl(struct ufs_hba *hba)
 hba-&amp;gt;outstanding_reqs ^= completed_reqs;
 
 /* Reset interrupt aggregation counters */
-ufshcd_config_int_aggr(hba, INT_AGGR_RESET);
+if (int_aggr_reset)
+ufshcd_config_int_aggr(hba, INT_AGGR_RESET);
 }
 
 /**
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1772,8 +1943,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_async_scan(void *data, async_cookie_t cookie)
 int ret;
 
 ret = ufshcd_link_startup(hba);
-if (!ret)
-scsi_scan_host(hba-&amp;gt;host);
+if (ret)
+goto out;
+
+ret = ufshcd_validate_dev_connection(hba);
+if (ret)
+goto out;
+
+scsi_scan_host(hba-&amp;gt;host);
+out:
+return;
 }
 
 static struct scsi_host_template ufshcd_driver_template = {
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 974bd07..558d2f4 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -102,6 +102,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct uic_command {
  * &amp;lt; at &amp;gt;command_type: SCSI, UFS, Query.
  * &amp;lt; at &amp;gt;task_tag: Task tag of the command
  * &amp;lt; at &amp;gt;lun: LUN of the command
+ * &amp;lt; at &amp;gt;intr_cmd: Interrupt command (doesn't participate in interrupt aggregation)
+ * &amp;lt; at &amp;gt;completion: holds the state of completion (used for internal commands)
  */
 struct ufshcd_lrb {
 struct utp_transfer_req_desc *utr_descriptor_ptr;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -117,6 +119,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct ufshcd_lrb {
 int command_type;
 int task_tag;
 unsigned int lun;
+bool intr_cmd;
+struct completion *completion;
 };
 
 /**
&lt;/pre&gt;</description>
    <dc:creator>Santosh Y</dc:creator>
    <dc:date>2013-05-19T08:21:41</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82080">
    <title>[PATCH 5/8] scsi: ufs: rework link start-up process</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82080</link>
    <description>&lt;pre&gt;From: Seungwon Jeon &amp;lt;tgih.jun&amp;lt; at &amp;gt;samsung.com&amp;gt;

Link start-up requires long time with multiphase handshakes
between UFS host and device. This affects driver's probe time.
This patch let link start-up run asynchronously. Link start-up
will be executed at the end of prove separately.
Along with this change, the following is worked.

Defined completion time of uic command to avoid a permanent wait.
Added mutex to guarantee of uic command at a time.
Adapted some sequence of controller initialization after link statup
according to HCI standard.

Signed-off-by: Seungwon Jeon &amp;lt;tgih.jun&amp;lt; at &amp;gt;samsung.com&amp;gt;
Signed-off-by: Sujit Reddy Thumma &amp;lt;sthumma&amp;lt; at &amp;gt;codeaurora.org&amp;gt;
Tested-by: Maya Erez &amp;lt;merez&amp;lt; at &amp;gt;codeaurora.org&amp;gt;
Signed-off-by: Santosh Y &amp;lt;santoshsy&amp;lt; at &amp;gt;gmail.com&amp;gt;

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index b1ac21e..0c570c0 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -33,11 +33,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
  * this program.
  */
 
+#include &amp;lt;linux/async.h&amp;gt;
+
 #include "ufshcd.h"
 
 #define UFSHCD_ENABLE_INTRS(UTP_TRANSFER_REQ_COMPL |\
  UTP_TASK_REQ_COMPL |\
  UFSHCD_ERROR_MASK)
+/* UIC command timeout, unit: ms */
+#define UIC_CMD_TIMEOUT500
 
 enum {
 UFSHCD_MAX_CHANNEL= 0,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -401,24 +405,122 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline void ufshcd_hba_capabilities(struct ufs_hba *hba)
 }
 
 /**
- * ufshcd_send_uic_command - Send UIC commands to unipro layers
+ * ufshcd_ready_for_uic_cmd - Check if controller is ready
+ *                            to accept UIC commands
  * &amp;lt; at &amp;gt;hba: per adapter instance
- * &amp;lt; at &amp;gt;uic_command: UIC command
+ * Return true on success, else false
+ */
+static inline bool ufshcd_ready_for_uic_cmd(struct ufs_hba *hba)
+{
+if (ufshcd_readl(hba, REG_CONTROLLER_STATUS) &amp;amp; UIC_COMMAND_READY)
+return true;
+else
+return false;
+}
+
+/**
+ * ufshcd_dispatch_uic_cmd - Dispatch UIC commands to unipro layers
+ * &amp;lt; at &amp;gt;hba: per adapter instance
+ * &amp;lt; at &amp;gt;uic_cmd: UIC command
+ *
+ * Mutex must be held.
  */
 static inline void
-ufshcd_send_uic_command(struct ufs_hba *hba, struct uic_command *uic_cmnd)
+ufshcd_dispatch_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
 {
+WARN_ON(hba-&amp;gt;active_uic_cmd);
+
+hba-&amp;gt;active_uic_cmd = uic_cmd;
+
 /* Write Args */
-ufshcd_writel(hba, uic_cmnd-&amp;gt;argument1, REG_UIC_COMMAND_ARG_1);
-ufshcd_writel(hba, uic_cmnd-&amp;gt;argument2, REG_UIC_COMMAND_ARG_2);
-ufshcd_writel(hba, uic_cmnd-&amp;gt;argument3, REG_UIC_COMMAND_ARG_3);
+ufshcd_writel(hba, uic_cmd-&amp;gt;argument1, REG_UIC_COMMAND_ARG_1);
+ufshcd_writel(hba, uic_cmd-&amp;gt;argument2, REG_UIC_COMMAND_ARG_2);
+ufshcd_writel(hba, uic_cmd-&amp;gt;argument3, REG_UIC_COMMAND_ARG_3);
 
 /* Write UIC Cmd */
-ufshcd_writel(hba, uic_cmnd-&amp;gt;command &amp;amp; COMMAND_OPCODE_MASK,
+ufshcd_writel(hba, uic_cmd-&amp;gt;command &amp;amp; COMMAND_OPCODE_MASK,
       REG_UIC_COMMAND);
 }
 
 /**
+ * ufshcd_wait_for_uic_cmd - Wait complectioin of UIC command
+ * &amp;lt; at &amp;gt;hba: per adapter instance
+ * &amp;lt; at &amp;gt;uic_command: UIC command
+ *
+ * Must be called with mutex held.
+ * Returns 0 only if success.
+ */
+static int
+ufshcd_wait_for_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
+{
+int ret;
+unsigned long flags;
+
+if (wait_for_completion_timeout(&amp;amp;uic_cmd-&amp;gt;done,
+msecs_to_jiffies(UIC_CMD_TIMEOUT)))
+ret = uic_cmd-&amp;gt;argument2 &amp;amp; MASK_UIC_COMMAND_RESULT;
+else
+ret = -ETIMEDOUT;
+
+spin_lock_irqsave(hba-&amp;gt;host-&amp;gt;host_lock, flags);
+hba-&amp;gt;active_uic_cmd = NULL;
+spin_unlock_irqrestore(hba-&amp;gt;host-&amp;gt;host_lock, flags);
+
+return ret;
+}
+
+/**
+ * __ufshcd_send_uic_cmd - Send UIC commands and retrieve the result
+ * &amp;lt; at &amp;gt;hba: per adapter instance
+ * &amp;lt; at &amp;gt;uic_cmd: UIC command
+ *
+ * Identical to ufshcd_send_uic_cmd() expect mutex. Must be called
+ * with mutex held.
+ * Returns 0 only if success.
+ */
+static int
+__ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
+{
+int ret;
+unsigned long flags;
+
+if (!ufshcd_ready_for_uic_cmd(hba)) {
+dev_err(hba-&amp;gt;dev,
+"Controller not ready to accept UIC commands\n");
+return -EIO;
+}
+
+init_completion(&amp;amp;uic_cmd-&amp;gt;done);
+
+spin_lock_irqsave(hba-&amp;gt;host-&amp;gt;host_lock, flags);
+ufshcd_dispatch_uic_cmd(hba, uic_cmd);
+spin_unlock_irqrestore(hba-&amp;gt;host-&amp;gt;host_lock, flags);
+
+ret = ufshcd_wait_for_uic_cmd(hba, uic_cmd);
+
+return ret;
+}
+
+/**
+ * ufshcd_send_uic_cmd - Send UIC commands and retrieve the result
+ * &amp;lt; at &amp;gt;hba: per adapter instance
+ * &amp;lt; at &amp;gt;uic_cmd: UIC command
+ *
+ * Returns 0 only if success.
+ */
+static int
+ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
+{
+int ret;
+
+mutex_lock(&amp;amp;hba-&amp;gt;uic_cmd_mutex);
+ret = __ufshcd_send_uic_cmd(hba, uic_cmd);
+mutex_unlock(&amp;amp;hba-&amp;gt;uic_cmd_mutex);
+
+return ret;
+}
+
+/**
  * ufshcd_map_sg - Map scatter-gather list to prdt
  * &amp;lt; at &amp;gt;lrbp - pointer to local reference block
  *
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -858,34 +960,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_host_memory_configure(struct ufs_hba *hba)
  */
 static int ufshcd_dme_link_startup(struct ufs_hba *hba)
 {
-struct uic_command *uic_cmd;
-unsigned long flags;
-
-/* check if controller is ready to accept UIC commands */
-if ((ufshcd_readl(hba, REG_CONTROLLER_STATUS) &amp;amp;
-    UIC_COMMAND_READY) == 0x0) {
-dev_err(hba-&amp;gt;dev,
-"Controller not ready"
-" to accept UIC commands\n");
-return -EIO;
-}
+struct uic_command uic_cmd = {0};
+int ret;
 
-spin_lock_irqsave(hba-&amp;gt;host-&amp;gt;host_lock, flags);
+uic_cmd.command = UIC_CMD_DME_LINK_STARTUP;
 
-/* form UIC command */
-uic_cmd = &amp;amp;hba-&amp;gt;active_uic_cmd;
-uic_cmd-&amp;gt;command = UIC_CMD_DME_LINK_STARTUP;
-uic_cmd-&amp;gt;argument1 = 0;
-uic_cmd-&amp;gt;argument2 = 0;
-uic_cmd-&amp;gt;argument3 = 0;
-
-/* enable UIC related interrupts */
-ufshcd_enable_intr(hba, UIC_COMMAND_COMPL);
-
-/* sending UIC commands to controller */
-ufshcd_send_uic_command(hba, uic_cmd);
-spin_unlock_irqrestore(hba-&amp;gt;host-&amp;gt;host_lock, flags);
-return 0;
+ret = ufshcd_send_uic_cmd(hba, &amp;amp;uic_cmd);
+if (ret)
+dev_err(hba-&amp;gt;dev,
+"dme-link-startup: error code %d\n", ret);
+return ret;
 }
 
 /**
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -894,9 +978,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ufshcd_dme_link_startup(struct ufs_hba *hba)
  *
  * To bring UFS host controller to operational state,
  * 1. Check if device is present
- * 2. Configure run-stop-registers
- * 3. Enable required interrupts
- * 4. Configure interrupt aggregation
+ * 2. Enable required interrupts
+ * 3. Configure interrupt aggregation
+ * 4. Program UTRL and UTMRL base addres
+ * 5. Configure run-stop-registers
  *
  * Returns 0 on success, non-zero value on failure
  */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -913,6 +998,22 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ufshcd_make_hba_operational(struct ufs_hba *hba)
 goto out;
 }
 
+/* Enable required interrupts */
+ufshcd_enable_intr(hba, UFSHCD_ENABLE_INTRS);
+
+/* Configure interrupt aggregation */
+ufshcd_config_int_aggr(hba, INT_AGGR_CONFIG);
+
+/* Configure UTRL and UTMRL base address registers */
+ufshcd_writel(hba, lower_32_bits(hba-&amp;gt;utrdl_dma_addr),
+REG_UTP_TRANSFER_REQ_LIST_BASE_L);
+ufshcd_writel(hba, upper_32_bits(hba-&amp;gt;utrdl_dma_addr),
+REG_UTP_TRANSFER_REQ_LIST_BASE_H);
+ufshcd_writel(hba, lower_32_bits(hba-&amp;gt;utmrdl_dma_addr),
+REG_UTP_TASK_REQ_LIST_BASE_L);
+ufshcd_writel(hba, upper_32_bits(hba-&amp;gt;utmrdl_dma_addr),
+REG_UTP_TASK_REQ_LIST_BASE_H);
+
 /*
  * UCRDY, UTMRLDY and UTRLRDY bits must be 1
  * DEI, HEI bits must be 0
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -926,17 +1027,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ufshcd_make_hba_operational(struct ufs_hba *hba)
 goto out;
 }
 
-/* Enable required interrupts */
-ufshcd_enable_intr(hba, UFSHCD_ENABLE_INTRS);
-
-/* Configure interrupt aggregation */
-ufshcd_config_int_aggr(hba, INT_AGGR_CONFIG);
-
 if (hba-&amp;gt;ufshcd_state == UFSHCD_STATE_RESET)
 scsi_unblock_requests(hba-&amp;gt;host);
 
 hba-&amp;gt;ufshcd_state = UFSHCD_STATE_OPERATIONAL;
-scsi_scan_host(hba-&amp;gt;host);
+
 out:
 return err;
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1005,34 +1100,28 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ufshcd_hba_enable(struct ufs_hba *hba)
 }
 
 /**
- * ufshcd_initialize_hba - start the initialization process
+ * ufshcd_link_startup - Initialize unipro link startup
  * &amp;lt; at &amp;gt;hba: per adapter instance
  *
- * 1. Enable the controller via ufshcd_hba_enable.
- * 2. Program the Transfer Request List Address with the starting address of
- * UTRDL.
- * 3. Program the Task Management Request List Address with starting address
- * of UTMRDL.
- *
- * Returns 0 on success, non-zero value on failure.
+ * Returns 0 for success, non-zero in case of failure
  */
-static int ufshcd_initialize_hba(struct ufs_hba *hba)
+static int ufshcd_link_startup(struct ufs_hba *hba)
 {
-if (ufshcd_hba_enable(hba))
-return -EIO;
+int ret;
 
-/* Configure UTRL and UTMRL base address registers */
-ufshcd_writel(hba, lower_32_bits(hba-&amp;gt;utrdl_dma_addr),
-      REG_UTP_TRANSFER_REQ_LIST_BASE_L);
-ufshcd_writel(hba, upper_32_bits(hba-&amp;gt;utrdl_dma_addr),
-      REG_UTP_TRANSFER_REQ_LIST_BASE_H);
-ufshcd_writel(hba, lower_32_bits(hba-&amp;gt;utmrdl_dma_addr),
-      REG_UTP_TASK_REQ_LIST_BASE_L);
-ufshcd_writel(hba, upper_32_bits(hba-&amp;gt;utmrdl_dma_addr),
-      REG_UTP_TASK_REQ_LIST_BASE_H);
+/* enable UIC related interrupts */
+ufshcd_enable_intr(hba, UIC_COMMAND_COMPL);
 
-/* Initialize unipro link startup procedure */
-return ufshcd_dme_link_startup(hba);
+ret = ufshcd_dme_link_startup(hba);
+if (ret)
+goto out;
+
+ret = ufshcd_make_hba_operational(hba);
+
+out:
+if (ret)
+dev_err(hba-&amp;gt;dev, "link startup failed %d\n", ret);
+return ret;
 }
 
 /**
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1072,12 +1161,19 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ufshcd_do_reset(struct ufs_hba *hba)
 hba-&amp;gt;outstanding_reqs = 0;
 hba-&amp;gt;outstanding_tasks = 0;
 
-/* start the initialization process */
-if (ufshcd_initialize_hba(hba)) {
+/* Host controller enable */
+if (ufshcd_hba_enable(hba)) {
 dev_err(hba-&amp;gt;dev,
 "Reset: Controller initialization failed\n");
 return FAILED;
 }
+
+if (ufshcd_link_startup(hba)) {
+dev_err(hba-&amp;gt;dev,
+"Reset: Link start-up failed\n");
+return FAILED;
+}
+
 return SUCCESS;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1330,6 +1426,19 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
 }
 
 /**
+ * ufshcd_uic_cmd_compl - handle completion of uic command
+ * &amp;lt; at &amp;gt;hba: per adapter instance
+ */
+static void ufshcd_uic_cmd_compl(struct ufs_hba *hba)
+{
+if (hba-&amp;gt;active_uic_cmd) {
+hba-&amp;gt;active_uic_cmd-&amp;gt;argument2 |=
+ufshcd_get_uic_cmd_result(hba);
+complete(&amp;amp;hba-&amp;gt;active_uic_cmd-&amp;gt;done);
+}
+}
+
+/**
  * ufshcd_transfer_req_compl - handle SCSI and query command completion
  * &amp;lt; at &amp;gt;hba: per adapter instance
  */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1369,28 +1478,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_transfer_req_compl(struct ufs_hba *hba)
 }
 
 /**
- * ufshcd_uic_cc_handler - handle UIC command completion
- * &amp;lt; at &amp;gt;work: pointer to a work queue structure
- *
- * Returns 0 on success, non-zero value on failure
- */
-static void ufshcd_uic_cc_handler (struct work_struct *work)
-{
-struct ufs_hba *hba;
-
-hba = container_of(work, struct ufs_hba, uic_workq);
-
-if ((hba-&amp;gt;active_uic_cmd.command == UIC_CMD_DME_LINK_STARTUP) &amp;amp;&amp;amp;
-    !(ufshcd_get_uic_cmd_result(hba))) {
-
-if (ufshcd_make_hba_operational(hba))
-dev_err(hba-&amp;gt;dev,
-"cc: hba not operational state\n");
-return;
-}
-}
-
-/**
  * ufshcd_fatal_err_handler - handle fatal errors
  * &amp;lt; at &amp;gt;hba: per adapter instance
  */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1451,7 +1538,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status)
 ufshcd_err_handler(hba);
 
 if (intr_status &amp;amp; UIC_COMMAND_COMPL)
-schedule_work(&amp;amp;hba-&amp;gt;uic_workq);
+ufshcd_uic_cmd_compl(hba);
 
 if (intr_status &amp;amp; UTP_TASK_REQ_COMPL)
 ufshcd_tmc_handler(hba);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1674,6 +1761,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out:
 return err;
 }
 
+/**
+ * ufshcd_async_scan - asynchronous execution for link startup
+ * &amp;lt; at &amp;gt;data: data pointer to pass to this function
+ * &amp;lt; at &amp;gt;cookie: cookie data
+ */
+static void ufshcd_async_scan(void *data, async_cookie_t cookie)
+{
+struct ufs_hba *hba = (struct ufs_hba *)data;
+int ret;
+
+ret = ufshcd_link_startup(hba);
+if (!ret)
+scsi_scan_host(hba-&amp;gt;host);
+}
+
 static struct scsi_host_template ufshcd_driver_template = {
 .module= THIS_MODULE,
 .name= UFSHCD,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1835,12 +1937,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle,
 init_waitqueue_head(&amp;amp;hba-&amp;gt;ufshcd_tm_wait_queue);
 
 /* Initialize work queues */
-INIT_WORK(&amp;amp;hba-&amp;gt;uic_workq, ufshcd_uic_cc_handler);
 INIT_WORK(&amp;amp;hba-&amp;gt;feh_workq, ufshcd_fatal_err_handler);
 
 /* Initialize mutex for query requests */
 mutex_init(&amp;amp;hba-&amp;gt;query.lock_ufs_query);
 
+/* Initialize UIC command mutex */
+mutex_init(&amp;amp;hba-&amp;gt;uic_cmd_mutex);
+
 /* IRQ registration */
 err = request_irq(irq, ufshcd_intr, IRQF_SHARED, UFSHCD, hba);
 if (err) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1861,14 +1965,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle,
 goto out_free_irq;
 }
 
-/* Initialization routine */
-err = ufshcd_initialize_hba(hba);
+/* Host controller enable */
+err = ufshcd_hba_enable(hba);
 if (err) {
-dev_err(hba-&amp;gt;dev, "Initialization failed\n");
+dev_err(hba-&amp;gt;dev, "Host controller enable failed\n");
 goto out_remove_scsi_host;
 }
+
 *hba_handle = hba;
 
+async_schedule(ufshcd_async_scan, hba);
+
 return 0;
 
 out_remove_scsi_host:
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index d98e046..974bd07 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -51,6 +51,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include &amp;lt;linux/bitops.h&amp;gt;
 #include &amp;lt;linux/pm_runtime.h&amp;gt;
 #include &amp;lt;linux/clk.h&amp;gt;
+#include &amp;lt;linux/completion.h&amp;gt;
 
 #include &amp;lt;asm/irq.h&amp;gt;
 #include &amp;lt;asm/byteorder.h&amp;gt;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -76,6 +77,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
  * &amp;lt; at &amp;gt;argument3: UIC command argument 3
  * &amp;lt; at &amp;gt;cmd_active: Indicate if UIC command is outstanding
  * &amp;lt; at &amp;gt;result: UIC command result
+ * &amp;lt; at &amp;gt;done: UIC command completion
  */
 struct uic_command {
 u32 command;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -84,6 +86,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct uic_command {
 u32 argument3;
 int cmd_active;
 int result;
+struct completion done;
 };
 
 /**
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -150,11 +153,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct ufs_query {
  * &amp;lt; at &amp;gt;ufs_version: UFS Version to which controller complies
  * &amp;lt; at &amp;gt;irq: Irq number of the controller
  * &amp;lt; at &amp;gt;active_uic_cmd: handle of active UIC command
+ * &amp;lt; at &amp;gt;uic_cmd_mutex: mutex for uic command
  * &amp;lt; at &amp;gt;ufshcd_tm_wait_queue: wait queue for task management
  * &amp;lt; at &amp;gt;tm_condition: condition variable for task management
  * &amp;lt; at &amp;gt;ufshcd_state: UFSHCD states
  * &amp;lt; at &amp;gt;intr_mask: Interrupt Mask Bits
- * &amp;lt; at &amp;gt;uic_workq: Work queue for UIC completion handling
  * &amp;lt; at &amp;gt;feh_workq: Work queue for fatal controller error handling
  * &amp;lt; at &amp;gt;errors: HBA errors
  * &amp;lt; at &amp;gt;query: query request information
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -186,7 +189,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct ufs_hba {
 u32 ufs_version;
 unsigned int irq;
 
-struct uic_command active_uic_cmd;
+struct uic_command *active_uic_cmd;
+struct mutex uic_cmd_mutex;
+
 wait_queue_head_t ufshcd_tm_wait_queue;
 unsigned long tm_condition;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -194,7 +199,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct ufs_hba {
 u32 intr_mask;
 
 /* Work Queues */
-struct work_struct uic_workq;
 struct work_struct feh_workq;
 
 /* HBA Errors */
&lt;/pre&gt;</description>
    <dc:creator>Santosh Y</dc:creator>
    <dc:date>2013-05-19T08:21:40</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82079">
    <title>[PATCH 4/8] scsi: ufs: remove version check before IS reg clear</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82079</link>
    <description>&lt;pre&gt;From: Seungwon Jeon &amp;lt;tgih.jun&amp;lt; at &amp;gt;samsung.com&amp;gt;

There is no need to check the version to clear
the interrupt status. And the order is changed
prior to actual handling.

Signed-off-by: Seungwon Jeon &amp;lt;tgih.jun&amp;lt; at &amp;gt;samsung.com&amp;gt;
Tested-by: Maya Erez &amp;lt;merez&amp;lt; at &amp;gt;codeaurora.org&amp;gt;
Signed-off-by: Santosh Y &amp;lt;santoshsy&amp;lt; at &amp;gt;gmail.com&amp;gt;

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index aa2c8d2..b1ac21e 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1478,11 +1478,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static irqreturn_t ufshcd_intr(int irq, void *__hba)
 intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
 
 if (intr_status) {
+ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS);
 ufshcd_sl_intr(hba, intr_status);
-
-/* If UFSHCI 1.0 then clear interrupt status register */
-if (hba-&amp;gt;ufs_version == UFSHCI_VERSION_10)
-ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS);
 retval = IRQ_HANDLED;
 }
 spin_unlock(hba-&amp;gt;host-&amp;gt;host_lock);
&lt;/pre&gt;</description>
    <dc:creator>Santosh Y</dc:creator>
    <dc:date>2013-05-19T08:21:39</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82078">
    <title>[PATCH 3/8] scsi: ufs: amend interrupt configuration</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82078</link>
    <description>&lt;pre&gt;From: Seungwon Jeon &amp;lt;tgih.jun&amp;lt; at &amp;gt;samsung.com&amp;gt;

It makes interrupt setting more flexible especially
for disabling. And wrong bit mask is fixed for ver 1.0.
[17:16] is added for mask.

Signed-off-by: Seungwon Jeon &amp;lt;tgih.jun&amp;lt; at &amp;gt;samsung.com&amp;gt;
Tested-by: Maya Erez &amp;lt;merez&amp;lt; at &amp;gt;codeaurora.org&amp;gt;
Signed-off-by: Santosh Y &amp;lt;santoshsy&amp;lt; at &amp;gt;gmail.com&amp;gt;

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 38412a6..aa2c8d2 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -35,6 +35,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 #include "ufshcd.h"
 
+#define UFSHCD_ENABLE_INTRS(UTP_TRANSFER_REQ_COMPL |\
+ UTP_TASK_REQ_COMPL |\
+ UFSHCD_ERROR_MASK)
+
 enum {
 UFSHCD_MAX_CHANNEL= 0,
 UFSHCD_MAX_ID= 1,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -64,6 +68,20 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; enum {
 };
 
 /**
+ * ufshcd_get_intr_mask - Get the interrupt bit mask
+ * &amp;lt; at &amp;gt;hba - Pointer to adapter instance
+ *
+ * Returns interrupt bit mask per version
+ */
+static inline u32 ufshcd_get_intr_mask(struct ufs_hba *hba)
+{
+if (hba-&amp;gt;ufs_version == UFSHCI_VERSION_10)
+return INTERRUPT_MASK_ALL_VER_10;
+else
+return INTERRUPT_MASK_ALL_VER_11;
+}
+
+/**
  * ufshcd_get_ufs_version - Get the UFS version supported by the HBA
  * &amp;lt; at &amp;gt;hba - Pointer to adapter instance
  *
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -441,25 +459,45 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ufshcd_map_sg(struct ufshcd_lrb *lrbp)
 }
 
 /**
- * ufshcd_int_config - enable/disable interrupts
+ * ufshcd_enable_intr - enable interrupts
  * &amp;lt; at &amp;gt;hba: per adapter instance
- * &amp;lt; at &amp;gt;option: interrupt option
+ * &amp;lt; at &amp;gt;intrs: interrupt bits
  */
-static void ufshcd_int_config(struct ufs_hba *hba, u32 option)
+static void ufshcd_enable_intr(struct ufs_hba *hba, u32 intrs)
 {
-switch (option) {
-case UFSHCD_INT_ENABLE:
-ufshcd_writel(hba, hba-&amp;gt;int_enable_mask, REG_INTERRUPT_ENABLE);
-break;
-case UFSHCD_INT_DISABLE:
-if (hba-&amp;gt;ufs_version == UFSHCI_VERSION_10)
-ufshcd_writel(hba, INTERRUPT_DISABLE_MASK_10,
-      REG_INTERRUPT_ENABLE);
-else
-ufshcd_writel(hba, INTERRUPT_DISABLE_MASK_11,
-      REG_INTERRUPT_ENABLE);
-break;
+u32 set = ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
+
+if (hba-&amp;gt;ufs_version == UFSHCI_VERSION_10) {
+u32 rw;
+rw = set &amp;amp; INTERRUPT_MASK_RW_VER_10;
+set = rw | ((set ^ intrs) &amp;amp; intrs);
+} else {
+set |= intrs;
+}
+
+ufshcd_writel(hba, set, REG_INTERRUPT_ENABLE);
+}
+
+/**
+ * ufshcd_disable_intr - disable interrupts
+ * &amp;lt; at &amp;gt;hba: per adapter instance
+ * &amp;lt; at &amp;gt;intrs: interrupt bits
+ */
+static void ufshcd_disable_intr(struct ufs_hba *hba, u32 intrs)
+{
+u32 set = ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
+
+if (hba-&amp;gt;ufs_version == UFSHCI_VERSION_10) {
+u32 rw;
+rw = (set &amp;amp; INTERRUPT_MASK_RW_VER_10) &amp;amp;
+~(intrs &amp;amp; INTERRUPT_MASK_RW_VER_10);
+set = rw | ((set &amp;amp; intrs) &amp;amp; ~INTERRUPT_MASK_RW_VER_10);
+
+} else {
+set &amp;amp;= ~intrs;
 }
+
+ufshcd_writel(hba, set, REG_INTERRUPT_ENABLE);
 }
 
 /**
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -842,8 +880,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ufshcd_dme_link_startup(struct ufs_hba *hba)
 uic_cmd-&amp;gt;argument3 = 0;
 
 /* enable UIC related interrupts */
-hba-&amp;gt;int_enable_mask |= UIC_COMMAND_COMPL;
-ufshcd_int_config(hba, UFSHCD_INT_ENABLE);
+ufshcd_enable_intr(hba, UIC_COMMAND_COMPL);
 
 /* sending UIC commands to controller */
 ufshcd_send_uic_command(hba, uic_cmd);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -890,13 +927,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ufshcd_make_hba_operational(struct ufs_hba *hba)
 }
 
 /* Enable required interrupts */
-hba-&amp;gt;int_enable_mask |= (UTP_TRANSFER_REQ_COMPL |
- UIC_ERROR |
- UTP_TASK_REQ_COMPL |
- DEVICE_FATAL_ERROR |
- CONTROLLER_FATAL_ERROR |
- SYSTEM_BUS_FATAL_ERROR);
-ufshcd_int_config(hba, UFSHCD_INT_ENABLE);
+ufshcd_enable_intr(hba, UFSHCD_ENABLE_INTRS);
 
 /* Configure interrupt aggregation */
 ufshcd_config_int_aggr(hba, INT_AGGR_CONFIG);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1724,7 +1755,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_hba_free(struct ufs_hba *hba)
 void ufshcd_remove(struct ufs_hba *hba)
 {
 /* disable interrupts */
-ufshcd_int_config(hba, UFSHCD_INT_DISABLE);
+ufshcd_disable_intr(hba, hba-&amp;gt;intr_mask);
 
 ufshcd_hba_stop(hba);
 ufshcd_hba_free(hba);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1782,6 +1813,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle,
 /* Get UFS version supported by the controller */
 hba-&amp;gt;ufs_version = ufshcd_get_ufs_version(hba);
 
+/* Get Interrupt bit mask per version */
+hba-&amp;gt;intr_mask = ufshcd_get_intr_mask(hba);
+
 /* Allocate memory for host memory space */
 err = ufshcd_memory_alloc(hba);
 if (err) {
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 6429bed..d98e046 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -153,7 +153,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct ufs_query {
  * &amp;lt; at &amp;gt;ufshcd_tm_wait_queue: wait queue for task management
  * &amp;lt; at &amp;gt;tm_condition: condition variable for task management
  * &amp;lt; at &amp;gt;ufshcd_state: UFSHCD states
- * &amp;lt; at &amp;gt;int_enable_mask: Interrupt Mask Bits
+ * &amp;lt; at &amp;gt;intr_mask: Interrupt Mask Bits
  * &amp;lt; at &amp;gt;uic_workq: Work queue for UIC completion handling
  * &amp;lt; at &amp;gt;feh_workq: Work queue for fatal controller error handling
  * &amp;lt; at &amp;gt;errors: HBA errors
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -191,7 +191,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct ufs_hba {
 unsigned long tm_condition;
 
 u32 ufshcd_state;
-u32 int_enable_mask;
+u32 intr_mask;
 
 /* Work Queues */
 struct work_struct uic_workq;
diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h
index 4a86247..f1e1b74 100644
--- a/drivers/scsi/ufs/ufshci.h
+++ b/drivers/scsi/ufs/ufshci.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -232,10 +232,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; enum {
 /* Interrupt disable masks */
 enum {
 /* Interrupt disable mask for UFSHCI v1.0 */
-INTERRUPT_DISABLE_MASK_10= 0xFFFF,
+INTERRUPT_MASK_ALL_VER_10= 0x30FFF,
+INTERRUPT_MASK_RW_VER_10= 0x30000,
 
 /* Interrupt disable mask for UFSHCI v1.1 */
-INTERRUPT_DISABLE_MASK_11= 0x0,
+INTERRUPT_MASK_ALL_VER_11= 0x31FFF,
 };
 
 /*
&lt;/pre&gt;</description>
    <dc:creator>Santosh Y</dc:creator>
    <dc:date>2013-05-19T08:21:38</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82077">
    <title>[PATCH 2/8] scsi: ufs: wrap the i/o access operations</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82077</link>
    <description>&lt;pre&gt;From: Seungwon Jeon &amp;lt;tgih.jun&amp;lt; at &amp;gt;samsung.com&amp;gt;

Simplify operations with hiding mmio_base.

Signed-off-by: Seungwon Jeon &amp;lt;tgih.jun&amp;lt; at &amp;gt;samsung.com&amp;gt;
Tested-by: Maya Erez &amp;lt;merez&amp;lt; at &amp;gt;codeaurora.org&amp;gt;
Signed-off-by: Santosh Y &amp;lt;santoshsy&amp;lt; at &amp;gt;gmail.com&amp;gt;

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 4ddc8be..38412a6 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -71,7 +71,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; enum {
  */
 static inline u32 ufshcd_get_ufs_version(struct ufs_hba *hba)
 {
-return readl(hba-&amp;gt;mmio_base + REG_UFS_VERSION);
+return ufshcd_readl(hba, REG_UFS_VERSION);
 }
 
 /**
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -130,8 +130,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline int ufshcd_get_tm_free_slot(struct ufs_hba *hba)
  */
 static inline void ufshcd_utrl_clear(struct ufs_hba *hba, u32 pos)
 {
-writel(~(1 &amp;lt;&amp;lt; pos),
-(hba-&amp;gt;mmio_base + REG_UTP_TRANSFER_REQ_LIST_CLEAR));
+ufshcd_writel(hba, ~(1 &amp;lt;&amp;lt; pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR);
 }
 
 /**
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -165,7 +164,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline int ufshcd_get_lists_status(u32 reg)
  */
 static inline int ufshcd_get_uic_cmd_result(struct ufs_hba *hba)
 {
-return readl(hba-&amp;gt;mmio_base + REG_UIC_COMMAND_ARG_2) &amp;amp;
+return ufshcd_readl(hba, REG_UIC_COMMAND_ARG_2) &amp;amp;
        MASK_UIC_COMMAND_RESULT;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -238,18 +237,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; ufshcd_config_int_aggr(struct ufs_hba *hba, int option)
 {
 switch (option) {
 case INT_AGGR_RESET:
-writel((INT_AGGR_ENABLE |
-INT_AGGR_COUNTER_AND_TIMER_RESET),
-(hba-&amp;gt;mmio_base +
- REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL));
+ufshcd_writel(hba, INT_AGGR_ENABLE |
+      INT_AGGR_COUNTER_AND_TIMER_RESET,
+      REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL);
 break;
 case INT_AGGR_CONFIG:
-writel((INT_AGGR_ENABLE |
-INT_AGGR_PARAM_WRITE |
-INT_AGGR_COUNTER_THRESHOLD_VALUE |
-INT_AGGR_TIMEOUT_VALUE),
-(hba-&amp;gt;mmio_base +
- REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL));
+ufshcd_writel(hba, INT_AGGR_ENABLE | INT_AGGR_PARAM_WRITE |
+      INT_AGGR_COUNTER_THRESHOLD_VALUE |
+      INT_AGGR_TIMEOUT_VALUE,
+      REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL);
 break;
 }
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -262,12 +258,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; ufshcd_config_int_aggr(struct ufs_hba *hba, int option)
  */
 static void ufshcd_enable_run_stop_reg(struct ufs_hba *hba)
 {
-writel(UTP_TASK_REQ_LIST_RUN_STOP_BIT,
-       (hba-&amp;gt;mmio_base +
-REG_UTP_TASK_REQ_LIST_RUN_STOP));
-writel(UTP_TRANSFER_REQ_LIST_RUN_STOP_BIT,
-       (hba-&amp;gt;mmio_base +
-REG_UTP_TRANSFER_REQ_LIST_RUN_STOP));
+ufshcd_writel(hba, UTP_TASK_REQ_LIST_RUN_STOP_BIT,
+      REG_UTP_TASK_REQ_LIST_RUN_STOP);
+ufshcd_writel(hba, UTP_TRANSFER_REQ_LIST_RUN_STOP_BIT,
+      REG_UTP_TRANSFER_REQ_LIST_RUN_STOP);
 }
 
 /**
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -276,7 +270,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_enable_run_stop_reg(struct ufs_hba *hba)
  */
 static inline void ufshcd_hba_start(struct ufs_hba *hba)
 {
-writel(CONTROLLER_ENABLE , (hba-&amp;gt;mmio_base + REG_CONTROLLER_ENABLE));
+ufshcd_writel(hba, CONTROLLER_ENABLE, REG_CONTROLLER_ENABLE);
 }
 
 /**
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -287,7 +281,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline void ufshcd_hba_start(struct ufs_hba *hba)
  */
 static inline int ufshcd_is_hba_active(struct ufs_hba *hba)
 {
-return (readl(hba-&amp;gt;mmio_base + REG_CONTROLLER_ENABLE) &amp;amp; 0x1) ? 0 : 1;
+return (ufshcd_readl(hba, REG_CONTROLLER_ENABLE) &amp;amp; 0x1) ? 0 : 1;
 }
 
 /**
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -299,8 +293,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline
 void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag)
 {
 __set_bit(task_tag, &amp;amp;hba-&amp;gt;outstanding_reqs);
-writel((1 &amp;lt;&amp;lt; task_tag),
-       (hba-&amp;gt;mmio_base + REG_UTP_TRANSFER_REQ_DOOR_BELL));
+ufshcd_writel(hba, 1 &amp;lt;&amp;lt; task_tag, REG_UTP_TRANSFER_REQ_DOOR_BELL);
 }
 
 /**
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -381,8 +374,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void ufshcd_copy_query_response(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
  */
 static inline void ufshcd_hba_capabilities(struct ufs_hba *hba)
 {
-hba-&amp;gt;capabilities =
-readl(hba-&amp;gt;mmio_base + REG_CONTROLLER_CAPABILITIES);
+hba-&amp;gt;capabilities = ufshcd_readl(hba, REG_CONTROLLER_CAPABILITIES);
 
 /* nutrs and nutmrs are 0 based values */
 hba-&amp;gt;nutrs = (hba-&amp;gt;capabilities &amp;amp; MASK_TRANSFER_REQUESTS_SLOTS) + 1;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -399,16 +391,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline void
 ufshcd_send_uic_command(struct ufs_hba *hba, struct uic_command *uic_cmnd)
 {
 /* Write Args */
-writel(uic_cmnd-&amp;gt;argument1,
-      (hba-&amp;gt;mmio_base + REG_UIC_COMMAND_ARG_1));
-writel(uic_cmnd-&amp;gt;argument2,
-      (hba-&amp;gt;mmio_base + REG_UIC_COMMAND_ARG_2));
-writel(uic_cmnd-&amp;gt;argument3,
-      (hba-&amp;gt;mmio_base + REG_UIC_COMMAND_ARG_3));
+ufshcd_writel(hba, uic_cmnd-&amp;gt;argument1, REG_UIC_COMMAND_ARG_1);
+ufshcd_writel(hba, uic_cmnd-&amp;gt;argument2, REG_UIC_COMMAND_ARG_2);
+ufshcd_writel(hba, uic_cmnd-&amp;gt;argument3, REG_UIC_COMMAND_ARG_3);
 
 /* Write UIC Cmd */
-writel((uic_cmnd-&amp;gt;command &amp;amp; COMMAND_OPCODE_MASK),
-       (hba-&amp;gt;mmio_base + REG_UIC_COMMAND));
+ufshcd_writel(hba, uic_cmnd-&amp;gt;command &amp;amp; COMMAND_OPCODE_MASK,
+      REG_UIC_COMMAND);
 }
 
 /**
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -460,16 +449,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_int_config(struct ufs_hba *hba, u32 option)
 {
 switch (option) {
 case UFSHCD_INT_ENABLE:
-writel(hba-&amp;gt;int_enable_mask,
-      (hba-&amp;gt;mmio_base + REG_INTERRUPT_ENABLE));
+ufshcd_writel(hba, hba-&amp;gt;int_enable_mask, REG_INTERRUPT_ENABLE);
 break;
 case UFSHCD_INT_DISABLE:
 if (hba-&amp;gt;ufs_version == UFSHCI_VERSION_10)
-writel(INTERRUPT_DISABLE_MASK_10,
-      (hba-&amp;gt;mmio_base + REG_INTERRUPT_ENABLE));
+ufshcd_writel(hba, INTERRUPT_DISABLE_MASK_10,
+      REG_INTERRUPT_ENABLE);
 else
-writel(INTERRUPT_DISABLE_MASK_11,
-       (hba-&amp;gt;mmio_base + REG_INTERRUPT_ENABLE));
+ufshcd_writel(hba, INTERRUPT_DISABLE_MASK_11,
+      REG_INTERRUPT_ENABLE);
 break;
 }
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -836,7 +824,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ufshcd_dme_link_startup(struct ufs_hba *hba)
 unsigned long flags;
 
 /* check if controller is ready to accept UIC commands */
-if (((readl(hba-&amp;gt;mmio_base + REG_CONTROLLER_STATUS)) &amp;amp;
+if ((ufshcd_readl(hba, REG_CONTROLLER_STATUS) &amp;amp;
     UIC_COMMAND_READY) == 0x0) {
 dev_err(hba-&amp;gt;dev,
 "Controller not ready"
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -881,7 +869,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ufshcd_make_hba_operational(struct ufs_hba *hba)
 u32 reg;
 
 /* check if device present */
-reg = readl((hba-&amp;gt;mmio_base + REG_CONTROLLER_STATUS));
+reg = ufshcd_readl(hba, REG_CONTROLLER_STATUS);
 if (!ufshcd_is_device_present(reg)) {
 dev_err(hba-&amp;gt;dev, "cc: Device not present\n");
 err = -ENXIO;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1003,14 +991,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ufshcd_initialize_hba(struct ufs_hba *hba)
 return -EIO;
 
 /* Configure UTRL and UTMRL base address registers */
-writel(lower_32_bits(hba-&amp;gt;utrdl_dma_addr),
-       (hba-&amp;gt;mmio_base + REG_UTP_TRANSFER_REQ_LIST_BASE_L));
-writel(upper_32_bits(hba-&amp;gt;utrdl_dma_addr),
-       (hba-&amp;gt;mmio_base + REG_UTP_TRANSFER_REQ_LIST_BASE_H));
-writel(lower_32_bits(hba-&amp;gt;utmrdl_dma_addr),
-       (hba-&amp;gt;mmio_base + REG_UTP_TASK_REQ_LIST_BASE_L));
-writel(upper_32_bits(hba-&amp;gt;utmrdl_dma_addr),
-       (hba-&amp;gt;mmio_base + REG_UTP_TASK_REQ_LIST_BASE_H));
+ufshcd_writel(hba, lower_32_bits(hba-&amp;gt;utrdl_dma_addr),
+      REG_UTP_TRANSFER_REQ_LIST_BASE_L);
+ufshcd_writel(hba, upper_32_bits(hba-&amp;gt;utrdl_dma_addr),
+      REG_UTP_TRANSFER_REQ_LIST_BASE_H);
+ufshcd_writel(hba, lower_32_bits(hba-&amp;gt;utmrdl_dma_addr),
+      REG_UTP_TASK_REQ_LIST_BASE_L);
+ufshcd_writel(hba, upper_32_bits(hba-&amp;gt;utmrdl_dma_addr),
+      REG_UTP_TASK_REQ_LIST_BASE_H);
 
 /* Initialize unipro link startup procedure */
 return ufshcd_dme_link_startup(hba);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1323,8 +1311,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_transfer_req_compl(struct ufs_hba *hba)
 int index;
 
 lrb = hba-&amp;gt;lrb;
-tr_doorbell =
-readl(hba-&amp;gt;mmio_base + REG_UTP_TRANSFER_REQ_DOOR_BELL);
+tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
 completed_reqs = tr_doorbell ^ hba-&amp;gt;outstanding_reqs;
 
 for (index = 0; index &amp;lt; hba-&amp;gt;nutrs; index++) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1398,9 +1385,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_err_handler(struct ufs_hba *hba)
 goto fatal_eh;
 
 if (hba-&amp;gt;errors &amp;amp; UIC_ERROR) {
-
-reg = readl(hba-&amp;gt;mmio_base +
-    REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER);
+reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER);
 if (reg &amp;amp; UIC_DATA_LINK_LAYER_ERROR_PA_INIT)
 goto fatal_eh;
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1418,7 +1403,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_tmc_handler(struct ufs_hba *hba)
 {
 u32 tm_doorbell;
 
-tm_doorbell = readl(hba-&amp;gt;mmio_base + REG_UTP_TASK_REQ_DOOR_BELL);
+tm_doorbell = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);
 hba-&amp;gt;tm_condition = tm_doorbell ^ hba-&amp;gt;outstanding_tasks;
 wake_up_interruptible(&amp;amp;hba-&amp;gt;ufshcd_tm_wait_queue);
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1459,15 +1444,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static irqreturn_t ufshcd_intr(int irq, void *__hba)
 struct ufs_hba *hba = __hba;
 
 spin_lock(hba-&amp;gt;host-&amp;gt;host_lock);
-intr_status = readl(hba-&amp;gt;mmio_base + REG_INTERRUPT_STATUS);
+intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
 
 if (intr_status) {
 ufshcd_sl_intr(hba, intr_status);
 
 /* If UFSHCI 1.0 then clear interrupt status register */
 if (hba-&amp;gt;ufs_version == UFSHCI_VERSION_10)
-writel(intr_status,
-       (hba-&amp;gt;mmio_base + REG_INTERRUPT_STATUS));
+ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS);
 retval = IRQ_HANDLED;
 }
 spin_unlock(hba-&amp;gt;host-&amp;gt;host_lock);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1532,8 +1516,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; ufshcd_issue_tm_cmd(struct ufs_hba *hba,
 
 /* send command to the controller */
 __set_bit(free_slot, &amp;amp;hba-&amp;gt;outstanding_tasks);
-writel((1 &amp;lt;&amp;lt; free_slot),
-       (hba-&amp;gt;mmio_base + REG_UTP_TASK_REQ_DOOR_BELL));
+ufshcd_writel(hba, 1 &amp;lt;&amp;lt; free_slot, REG_UTP_TASK_REQ_DOOR_BELL);
 
 spin_unlock_irqrestore(host-&amp;gt;host_lock, flags);
 
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 336980b..6429bed 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -204,6 +204,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct ufs_hba {
 struct ufs_query query;
 };
 
+#define ufshcd_writel(hba, val, reg)\
+writel((val), (hba)-&amp;gt;mmio_base + (reg))
+#define ufshcd_readl(hba, reg)\
+readl((hba)-&amp;gt;mmio_base + (reg))
+
 int ufshcd_init(struct device *, struct ufs_hba ** , void __iomem * ,
 unsigned int);
 void ufshcd_remove(struct ufs_hba *);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -214,7 +219,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void ufshcd_remove(struct ufs_hba *);
  */
 static inline void ufshcd_hba_stop(struct ufs_hba *hba)
 {
-writel(CONTROLLER_DISABLE, (hba-&amp;gt;mmio_base + REG_CONTROLLER_ENABLE));
+ufshcd_writel(hba, CONTROLLER_DISABLE,  REG_CONTROLLER_ENABLE);
 }
 
 #endif /* End of Header */
&lt;/pre&gt;</description>
    <dc:creator>Santosh Y</dc:creator>
    <dc:date>2013-05-19T08:21:37</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82076">
    <title>[PATCH 1/8] scsi: ufs: add support for query requests</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82076</link>
    <description>&lt;pre&gt;From: Dolev Raviv &amp;lt;draviv&amp;lt; at &amp;gt;codeaurora.org&amp;gt;

Add support for sending UFS query requests through tagged command
queuing. This design allows queuing query requests in any open slot
along with other SCSI commands. In this way there is no need to
save a slot in the requests queue and decrease its size.

A query request is posing to a SCSI command to use native flow. But
unlike normal SCSI command flow, the data and response fields are
filled in UFS host data structure instead of passing as arguments
while queuing into SCSI mlqueue (mid-layer SCSI queue, the requests
from this queue are submitted to the device queue). As per specification
only one query request is allowed to be processed by device. Hence a
mutex lock for protecting data and response fields (hba-&amp;gt;query.request and
hba-&amp;gt;query.response) needs to be held while query request is in
progress.

The API for submitting a query request is ufs_query_request() in
ufshcd.c. This function is responsible for:
1. Obtaining the SCSI device from the host
2. Keeping the query mutex to prevent multiple queries
3. Storing the required data for sending a query request in ufs_hba
4. Queuing a SCSI vendor specific command to trigger a query request
   in the UFS driver.

The callers of ufs_query_request() are expected to fill the query
command data fields and are to provide an allocated response field
for the driver to fill response fields after request completion.

The request and response upiu is extended in a union to enable using the
same data structure, both for command upiu and query request upiu.

The query request flow is separated from the scsi command flow in:
1. Preparing the request
2. Validating response (error) codes
3. Copying data (only used for descriptor read/write query requests)
4. Copying response/sense

Data error can't be handled in the scsi command native flow. Hence,
we pass the code as without a change back to the submitting layer.

UPIU (UFS Protocol Information Unit) size is increased to 512 bytes
from 128. The UPIU header and the transaction specific fields (SCSI
command or Query Request OSF - Op-code Specific Fields) are 32 bytes
together, the rest is used to transfer extra request data (such as
descriptor in query requests). In order to accommodate the largest
descriptor in the UFS spec (256 bytes) we need to increase the UPIU
size.

Signed-off-by: Dolev Raviv &amp;lt;draviv&amp;lt; at &amp;gt;codeaurora.org&amp;gt;
Signed-off-by: Santosh Y &amp;lt;santoshsy&amp;lt; at &amp;gt;gmail.com&amp;gt;

diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 139bc06..086ff03 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -36,10 +36,20 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #ifndef _UFS_H
 #define _UFS_H
 
+#include &amp;lt;linux/mutex.h&amp;gt;
+#include &amp;lt;linux/types.h&amp;gt;
+
 #define MAX_CDB_SIZE16
+#define GENERAL_UPIU_REQUEST_SIZE 32
+#define UPIU_HEADER_DATA_SEGMENT_MAX_SIZE((ALIGNED_UPIU_SIZE) - \
+(GENERAL_UPIU_REQUEST_SIZE))
+#define QUERY_OSF_SIZE((GENERAL_UPIU_REQUEST_SIZE) - \
+(sizeof(struct utp_upiu_header)))
+#define UFS_QUERY_RESERVED_SCSI_CMD 0xCC
+#define UFS_QUERY_CMD_SIZE 10
 
 #define UPIU_HEADER_DWORD(byte3, byte2, byte1, byte0)\
-((byte3 &amp;lt;&amp;lt; 24) | (byte2 &amp;lt;&amp;lt; 16) |\
+cpu_to_be32((byte3 &amp;lt;&amp;lt; 24) | (byte2 &amp;lt;&amp;lt; 16) |\
  (byte1 &amp;lt;&amp;lt; 8) | (byte0))
 
 /*
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -62,7 +72,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; enum {
 UPIU_TRANSACTION_COMMAND= 0x01,
 UPIU_TRANSACTION_DATA_OUT= 0x02,
 UPIU_TRANSACTION_TASK_REQ= 0x04,
-UPIU_TRANSACTION_QUERY_REQ= 0x26,
+UPIU_TRANSACTION_QUERY_REQ= 0x16,
 };
 
 /* UTP UPIU Transaction Codes Target to Initiator */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -73,6 +83,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; enum {
 UPIU_TRANSACTION_TASK_RSP= 0x24,
 UPIU_TRANSACTION_READY_XFER= 0x31,
 UPIU_TRANSACTION_QUERY_RSP= 0x36,
+UPIU_TRANSACTION_REJECT_UPIU= 0x3F,
 };
 
 /* UPIU Read/Write flags */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -90,6 +101,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; enum {
 UPIU_TASK_ATTR_ACA= 0x03,
 };
 
+/* UPIU Query request function */
+enum {
+UPIU_QUERY_FUNC_STANDARD_READ_REQUEST = 0x01,
+UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST = 0x81,
+};
+
 /* UTP QUERY Transaction Specific Fields OpCode */
 enum {
 UPIU_QUERY_OPCODE_NOP= 0x0,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -103,6 +120,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; enum {
 UPIU_QUERY_OPCODE_TOGGLE_FLAG= 0x8,
 };
 
+/* Query response result code */
+enum {
+QUERY_RESULT_SUCCESS= 0x00,
+QUERY_RESULT_NOT_READABLE= 0xF6,
+QUERY_RESULT_NOT_WRITEABLE= 0xF7,
+QUERY_RESULT_ALREADY_WRITTEN= 0xF8,
+QUERY_RESULT_INVALID_LENGTH= 0xF9,
+QUERY_RESULT_INVALID_VALUE= 0xFA,
+QUERY_RESULT_INVALID_SELECTOR= 0xFB,
+QUERY_RESULT_INVALID_INDEX= 0xFC,
+QUERY_RESULT_INVALID_IDN= 0xFD,
+QUERY_RESULT_INVALID_OPCODE= 0xFE,
+QUERY_RESULT_GENERAL_FAILURE= 0xFF,
+};
+
 /* UTP Transfer Request Command Type (CT) */
 enum {
 UPIU_COMMAND_SET_TYPE_SCSI= 0x0,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -110,10 +142,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; enum {
 UPIU_COMMAND_SET_TYPE_QUERY= 0x2,
 };
 
+/* UTP Transfer Request Command Offset */
+#define UPIU_COMMAND_TYPE_OFFSET28
+
+/* Offset of the response code in the UPIU header */
+#define UPIU_RSP_CODE_OFFSET8
+
 enum {
 MASK_SCSI_STATUS= 0xFF,
 MASK_TASK_RESPONSE= 0xFF00,
 MASK_RSP_UPIU_RESULT= 0xFFFF,
+MASK_QUERY_DATA_SEG_LEN= 0xFFFF,
 };
 
 /* Task management service response */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -138,26 +177,59 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct utp_upiu_header {
 
 /**
  * struct utp_upiu_cmd - Command UPIU structure
- * &amp;lt; at &amp;gt;header: UPIU header structure DW-0 to DW-2
  * &amp;lt; at &amp;gt;data_transfer_len: Data Transfer Length DW-3
  * &amp;lt; at &amp;gt;cdb: Command Descriptor Block CDB DW-4 to DW-7
  */
 struct utp_upiu_cmd {
-struct utp_upiu_header header;
 u32 exp_data_transfer_len;
 u8 cdb[MAX_CDB_SIZE];
 };
 
 /**
- * struct utp_upiu_rsp - Response UPIU structure
- * &amp;lt; at &amp;gt;header: UPIU header DW-0 to DW-2
+ * struct utp_upiu_query - upiu request buffer structure for
+ * query request.
+ * &amp;lt; at &amp;gt;opcode: command to perform B-0
+ * &amp;lt; at &amp;gt;idn: a value that indicates the particular type of data B-1
+ * &amp;lt; at &amp;gt;index: Index to further identify data B-2
+ * &amp;lt; at &amp;gt;selector: Index to further identify data B-3
+ * &amp;lt; at &amp;gt;reserved_osf: spec reserved field B-4,5
+ * &amp;lt; at &amp;gt;length: number of descriptor bytes to read/write B-6,7
+ * &amp;lt; at &amp;gt;value: Attribute value to be written DW-6
+ * &amp;lt; at &amp;gt;reserved: spec reserved DW-7,8
+ */
+struct utp_upiu_query {
+u8 opcode;
+u8 idn;
+u8 index;
+u8 selector;
+u16 reserved_osf;
+u16 length;
+u32 value;
+u32 reserved[2];
+};
+
+/**
+ * struct utp_upiu_req - general upiu request structure
+ * &amp;lt; at &amp;gt;header:UPIU header structure DW-0 to DW-2
+ * &amp;lt; at &amp;gt;sc: fields structure for scsi command
+ * &amp;lt; at &amp;gt;qr: fields structure for query request
+ */
+struct utp_upiu_req {
+struct utp_upiu_header header;
+union {
+struct utp_upiu_cmd sc;
+struct utp_upiu_query qr;
+};
+};
+
+/**
+ * struct utp_cmd_rsp - Response UPIU structure
  * &amp;lt; at &amp;gt;residual_transfer_count: Residual transfer count DW-3
  * &amp;lt; at &amp;gt;reserved: Reserved double words DW-4 to DW-7
  * &amp;lt; at &amp;gt;sense_data_len: Sense data length DW-8 U16
  * &amp;lt; at &amp;gt;sense_data: Sense data field DW-8 to DW-12
  */
-struct utp_upiu_rsp {
-struct utp_upiu_header header;
+struct utp_cmd_rsp {
 u32 residual_transfer_count;
 u32 reserved[4];
 u16 sense_data_len;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -165,6 +237,20 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct utp_upiu_rsp {
 };
 
 /**
+ * struct utp_upiu_rsp - general upiu response structure
+ * &amp;lt; at &amp;gt;header: UPIU header structure DW-0 to DW-2
+ * &amp;lt; at &amp;gt;sc: fields structure for scsi command
+ * &amp;lt; at &amp;gt;qr: fields structure for query request
+ */
+struct utp_upiu_rsp {
+struct utp_upiu_header header;
+union {
+struct utp_cmd_rsp sc;
+struct utp_upiu_query qr;
+};
+};
+
+/**
  * struct utp_upiu_task_req - Task request UPIU structure
  * &amp;lt; at &amp;gt;header - UPIU header structure DW0 to DW-2
  * &amp;lt; at &amp;gt;input_param1: Input parameter 1 DW-3
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -194,4 +280,24 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct utp_upiu_task_rsp {
 u32 reserved[3];
 };
 
+/**
+ * struct ufs_query_req - parameters for building a query request
+ * &amp;lt; at &amp;gt;query_func: UPIU header query function
+ * &amp;lt; at &amp;gt;upiu_req: the query request data
+ */
+struct ufs_query_req {
+u8 query_func;
+struct utp_upiu_query upiu_req;
+};
+
+/**
+ * struct ufs_query_resp - UPIU QUERY
+ * &amp;lt; at &amp;gt;response: device response code
+ * &amp;lt; at &amp;gt;upiu_res: query response data
+ */
+struct ufs_query_res {
+u8 response;
+struct utp_upiu_query upiu_res;
+};
+
 #endif /* End of Header */
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index c32a478..4ddc8be 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -202,18 +202,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline void ufshcd_free_hba_memory(struct ufs_hba *hba)
 }
 
 /**
- * ufshcd_is_valid_req_rsp - checks if controller TR response is valid
+ * ufshcd_get_req_rsp - returns the TR response
  * &amp;lt; at &amp;gt;ucd_rsp_ptr: pointer to response UPIU
- *
- * This function checks the response UPIU for valid transaction type in
- * response field
- * Returns 0 on success, non-zero on failure
  */
 static inline int
-ufshcd_is_valid_req_rsp(struct utp_upiu_rsp *ucd_rsp_ptr)
+ufshcd_get_req_rsp(struct utp_upiu_rsp *ucd_rsp_ptr)
 {
-return ((be32_to_cpu(ucd_rsp_ptr-&amp;gt;header.dword_0) &amp;gt;&amp;gt; 24) ==
- UPIU_TRANSACTION_RESPONSE) ? 0 : DID_ERROR &amp;lt;&amp;lt; 16;
+return be32_to_cpu(ucd_rsp_ptr-&amp;gt;header.dword_0) &amp;gt;&amp;gt; 24;
 }
 
 /**
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -316,14 +311,71 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline void ufshcd_copy_sense_data(struct ufshcd_lrb *lrbp)
 {
 int len;
 if (lrbp-&amp;gt;sense_buffer) {
-len = be16_to_cpu(lrbp-&amp;gt;ucd_rsp_ptr-&amp;gt;sense_data_len);
+len = be16_to_cpu(lrbp-&amp;gt;ucd_rsp_ptr-&amp;gt;sc.sense_data_len);
 memcpy(lrbp-&amp;gt;sense_buffer,
-lrbp-&amp;gt;ucd_rsp_ptr-&amp;gt;sense_data,
+lrbp-&amp;gt;ucd_rsp_ptr-&amp;gt;sc.sense_data,
 min_t(int, len, SCSI_SENSE_BUFFERSIZE));
 }
 }
 
 /**
+ * ufshcd_query_to_cpu() - formats the received buffer in to the native cpu
+ * endian
+ * &amp;lt; at &amp;gt;response: upiu query response to convert
+ */
+static inline void ufshcd_query_to_cpu(struct utp_upiu_query *response)
+{
+response-&amp;gt;length = be16_to_cpu(response-&amp;gt;length);
+response-&amp;gt;value = be32_to_cpu(response-&amp;gt;value);
+}
+
+/**
+ * ufshcd_query_to_be() - formats the buffer before sending in to big endian
+ * &amp;lt; at &amp;gt;response: upiu query request to convert
+ */
+static inline void ufshcd_query_to_be(struct utp_upiu_query *request)
+{
+request-&amp;gt;length = cpu_to_be16(request-&amp;gt;length);
+request-&amp;gt;value = cpu_to_be32(request-&amp;gt;value);
+}
+
+/**
+ * ufshcd_copy_query_response() - Copy Query Response and descriptor
+ * &amp;lt; at &amp;gt;lrb - pointer to local reference block
+ * &amp;lt; at &amp;gt;query_res - pointer to the query result
+ */
+static
+void ufshcd_copy_query_response(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
+{
+struct ufs_query_res *query_res = hba-&amp;gt;query.response;
+
+/* Get the UPIU response */
+if (query_res) {
+query_res-&amp;gt;response = ufshcd_get_rsp_upiu_result(
+lrbp-&amp;gt;ucd_rsp_ptr) &amp;gt;&amp;gt; UPIU_RSP_CODE_OFFSET;
+
+memcpy(&amp;amp;query_res-&amp;gt;upiu_res, &amp;amp;lrbp-&amp;gt;ucd_rsp_ptr-&amp;gt;qr,
+QUERY_OSF_SIZE);
+ufshcd_query_to_cpu(&amp;amp;query_res-&amp;gt;upiu_res);
+}
+
+/* Get the descriptor */
+if (hba-&amp;gt;query.descriptor &amp;amp;&amp;amp; lrbp-&amp;gt;ucd_rsp_ptr-&amp;gt;qr.opcode ==
+UPIU_QUERY_OPCODE_READ_DESC) {
+u8 *descp = (u8 *)&amp;amp;lrbp-&amp;gt;ucd_rsp_ptr +
+GENERAL_UPIU_REQUEST_SIZE;
+u16 len;
+
+/* data segment length */
+len = be32_to_cpu(lrbp-&amp;gt;ucd_rsp_ptr-&amp;gt;header.dword_2) &amp;amp;
+MASK_QUERY_DATA_SEG_LEN;
+
+memcpy(hba-&amp;gt;query.descriptor, descp,
+min_t(u16, len, UPIU_HEADER_DATA_SEGMENT_MAX_SIZE));
+}
+}
+
+/**
  * ufshcd_hba_capabilities - Read controller capabilities
  * &amp;lt; at &amp;gt;hba: per adapter instance
  */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -423,76 +475,154 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_int_config(struct ufs_hba *hba, u32 option)
 }
 
 /**
- * ufshcd_compose_upiu - form UFS Protocol Information Unit(UPIU)
- * &amp;lt; at &amp;gt;lrb - pointer to local reference block
+ * ufshcd_prepare_req_desc - Fills the requests header
+ * descriptor according to request
+ * lrbp: pointer to local reference block
+ * upiu_flags: flags required in the header
  */
-static void ufshcd_compose_upiu(struct ufshcd_lrb *lrbp)
+static void ufshcd_prepare_req_desc(struct ufshcd_lrb *lrbp, u32 *upiu_flags)
 {
-struct utp_transfer_req_desc *req_desc;
-struct utp_upiu_cmd *ucd_cmd_ptr;
+struct utp_transfer_req_desc *req_desc = lrbp-&amp;gt;utr_descriptor_ptr;
+enum dma_data_direction cmd_dir =
+lrbp-&amp;gt;cmd-&amp;gt;sc_data_direction;
 u32 data_direction;
-u32 upiu_flags;
+u32 dword_0;
+
+if (cmd_dir == DMA_FROM_DEVICE) {
+data_direction = UTP_DEVICE_TO_HOST;
+*upiu_flags = UPIU_CMD_FLAGS_READ;
+} else if (cmd_dir == DMA_TO_DEVICE) {
+data_direction = UTP_HOST_TO_DEVICE;
+*upiu_flags = UPIU_CMD_FLAGS_WRITE;
+} else {
+data_direction = UTP_NO_DATA_TRANSFER;
+*upiu_flags = UPIU_CMD_FLAGS_NONE;
+}
 
-ucd_cmd_ptr = lrbp-&amp;gt;ucd_cmd_ptr;
-req_desc = lrbp-&amp;gt;utr_descriptor_ptr;
+dword_0 = data_direction | (lrbp-&amp;gt;command_type
+&amp;lt;&amp;lt; UPIU_COMMAND_TYPE_OFFSET);
 
-switch (lrbp-&amp;gt;command_type) {
-case UTP_CMD_TYPE_SCSI:
-if (lrbp-&amp;gt;cmd-&amp;gt;sc_data_direction == DMA_FROM_DEVICE) {
-data_direction = UTP_DEVICE_TO_HOST;
-upiu_flags = UPIU_CMD_FLAGS_READ;
-} else if (lrbp-&amp;gt;cmd-&amp;gt;sc_data_direction == DMA_TO_DEVICE) {
-data_direction = UTP_HOST_TO_DEVICE;
-upiu_flags = UPIU_CMD_FLAGS_WRITE;
-} else {
-data_direction = UTP_NO_DATA_TRANSFER;
-upiu_flags = UPIU_CMD_FLAGS_NONE;
-}
+/* Transfer request descriptor header fields */
+req_desc-&amp;gt;header.dword_0 = cpu_to_le32(dword_0);
 
-/* Transfer request descriptor header fields */
-req_desc-&amp;gt;header.dword_0 =
-cpu_to_le32(data_direction | UTP_SCSI_COMMAND);
+/*
+ * assigning invalid value for command status. Controller
+ * updates OCS on command completion, with the command
+ * status
+ */
+req_desc-&amp;gt;header.dword_2 =
+cpu_to_le32(OCS_INVALID_COMMAND_STATUS);
+}
 
-/*
- * assigning invalid value for command status. Controller
- * updates OCS on command completion, with the command
- * status
- */
-req_desc-&amp;gt;header.dword_2 =
-cpu_to_le32(OCS_INVALID_COMMAND_STATUS);
+static inline bool ufshcd_is_query_req(struct ufshcd_lrb *lrbp)
+{
+return lrbp-&amp;gt;cmd ? lrbp-&amp;gt;cmd-&amp;gt;cmnd[0] == UFS_QUERY_RESERVED_SCSI_CMD :
+false;
+}
 
-/* command descriptor fields */
-ucd_cmd_ptr-&amp;gt;header.dword_0 =
-cpu_to_be32(UPIU_HEADER_DWORD(UPIU_TRANSACTION_COMMAND,
-      upiu_flags,
-      lrbp-&amp;gt;lun,
-      lrbp-&amp;gt;task_tag));
-ucd_cmd_ptr-&amp;gt;header.dword_1 =
-cpu_to_be32(
-UPIU_HEADER_DWORD(UPIU_COMMAND_SET_TYPE_SCSI,
-  0,
-  0,
-  0));
-
-/* Total EHS length and Data segment length will be zero */
-ucd_cmd_ptr-&amp;gt;header.dword_2 = 0;
-
-ucd_cmd_ptr-&amp;gt;exp_data_transfer_len =
-cpu_to_be32(lrbp-&amp;gt;cmd-&amp;gt;sdb.length);
-
-memcpy(ucd_cmd_ptr-&amp;gt;cdb,
-       lrbp-&amp;gt;cmd-&amp;gt;cmnd,
-       (min_t(unsigned short,
-      lrbp-&amp;gt;cmd-&amp;gt;cmd_len,
-      MAX_CDB_SIZE)));
-break;
+/**
+ * ufshcd_prepare_utp_scsi_cmd_upiu() - fills the utp_transfer_req_desc,
+ * for scsi commands
+ * &amp;lt; at &amp;gt;lrbp - local reference block pointer
+ * &amp;lt; at &amp;gt;upiu_flags - flags
+ */
+static
+void ufshcd_prepare_utp_scsi_cmd_upiu(struct ufshcd_lrb *lrbp, u32 upiu_flags)
+{
+struct utp_upiu_req *ucd_req_ptr = lrbp-&amp;gt;ucd_req_ptr;
+
+/* command descriptor fields */
+ucd_req_ptr-&amp;gt;header.dword_0 = UPIU_HEADER_DWORD(
+UPIU_TRANSACTION_COMMAND, upiu_flags,
+lrbp-&amp;gt;lun, lrbp-&amp;gt;task_tag);
+ucd_req_ptr-&amp;gt;header.dword_1 = UPIU_HEADER_DWORD(
+UPIU_COMMAND_SET_TYPE_SCSI, 0, 0, 0);
+
+/* Total EHS length and Data segment length will be zero */
+ucd_req_ptr-&amp;gt;header.dword_2 = 0;
+
+ucd_req_ptr-&amp;gt;sc.exp_data_transfer_len =
+cpu_to_be32(lrbp-&amp;gt;cmd-&amp;gt;sdb.length);
+
+memcpy(ucd_req_ptr-&amp;gt;sc.cdb, lrbp-&amp;gt;cmd-&amp;gt;cmnd,
+(min_t(unsigned short, lrbp-&amp;gt;cmd-&amp;gt;cmd_len, MAX_CDB_SIZE)));
+}
+
+/**
+ * ufshcd_prepare_utp_query_req_upiu() - fills the utp_transfer_req_desc,
+ * for query requsts
+ * &amp;lt; at &amp;gt;hba: UFS hba
+ * &amp;lt; at &amp;gt;lrbp: local reference block pointer
+ * &amp;lt; at &amp;gt;upiu_flags: flags
+ */
+static void ufshcd_prepare_utp_query_req_upiu(struct ufs_hba *hba,
+struct ufshcd_lrb *lrbp,
+u32 upiu_flags)
+{
+struct utp_upiu_req *ucd_req_ptr = lrbp-&amp;gt;ucd_req_ptr;
+u16 len = hba-&amp;gt;query.request-&amp;gt;upiu_req.length;
+u8 *descp = (u8 *)lrbp-&amp;gt;ucd_req_ptr + GENERAL_UPIU_REQUEST_SIZE;
+
+/* Query request header */
+ucd_req_ptr-&amp;gt;header.dword_0 = UPIU_HEADER_DWORD(
+UPIU_TRANSACTION_QUERY_REQ, upiu_flags,
+lrbp-&amp;gt;lun, lrbp-&amp;gt;task_tag);
+ucd_req_ptr-&amp;gt;header.dword_1 = UPIU_HEADER_DWORD(
+0, hba-&amp;gt;query.request-&amp;gt;query_func, 0, 0);
+
+/* Data segment length */
+ucd_req_ptr-&amp;gt;header.dword_2 = UPIU_HEADER_DWORD(
+0, 0, len &amp;gt;&amp;gt; 8, (u8)len);
+
+/* Copy the Query Request buffer as is */
+memcpy(&amp;amp;lrbp-&amp;gt;ucd_req_ptr-&amp;gt;qr, &amp;amp;hba-&amp;gt;query.request-&amp;gt;upiu_req,
+QUERY_OSF_SIZE);
+ufshcd_query_to_be(&amp;amp;lrbp-&amp;gt;ucd_req_ptr-&amp;gt;qr);
+
+/* Copy the Descriptor */
+if (hba-&amp;gt;query.descriptor != NULL &amp;amp;&amp;amp; len &amp;gt; 0 &amp;amp;&amp;amp;
+(hba-&amp;gt;query.request-&amp;gt;upiu_req.opcode ==
+UPIU_QUERY_OPCODE_WRITE_DESC)) {
+memcpy(descp, hba-&amp;gt;query.descriptor,
+min_t(u16, len, UPIU_HEADER_DATA_SEGMENT_MAX_SIZE));
+}
+
+}
+
+/**
+ * ufshcd_compose_upiu - form UFS Protocol Information Unit(UPIU)
+ * &amp;lt; at &amp;gt;hba - UFS hba
+ * &amp;lt; at &amp;gt;lrb - pointer to local reference block
+ */
+static int ufshcd_compose_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
+{
+u32 upiu_flags;
+int ret = 0;
+
+switch (lrbp-&amp;gt;command_type) {
+case UTP_CMD_TYPE_SCSI:
 case UTP_CMD_TYPE_DEV_MANAGE:
-/* For query function implementation */
+ufshcd_prepare_req_desc(lrbp, &amp;amp;upiu_flags);
+if (lrbp-&amp;gt;command_type == UTP_CMD_TYPE_SCSI)
+ufshcd_prepare_utp_scsi_cmd_upiu(lrbp, upiu_flags);
+else
+ufshcd_prepare_utp_query_req_upiu(hba, lrbp,
+upiu_flags);
 break;
 case UTP_CMD_TYPE_UFS:
 /* For UFS native command implementation */
+dev_err(hba-&amp;gt;dev, "%s: UFS native command are not supported\n",
+__func__);
+ret = -ENOTSUPP;
+break;
+default:
+ret = -ENOTSUPP;
+dev_err(hba-&amp;gt;dev, "%s: unknown command type: 0x%x\n",
+__func__, lrbp-&amp;gt;command_type);
 break;
 } /* end of switch */
+
+return ret;
 }
 
 /**
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -527,10 +657,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 lrbp-&amp;gt;task_tag = tag;
 lrbp-&amp;gt;lun = cmd-&amp;gt;device-&amp;gt;lun;
 
-lrbp-&amp;gt;command_type = UTP_CMD_TYPE_SCSI;
+if (ufshcd_is_query_req(lrbp))
+lrbp-&amp;gt;command_type = UTP_CMD_TYPE_DEV_MANAGE;
+else
+lrbp-&amp;gt;command_type = UTP_CMD_TYPE_SCSI;
 
 /* form UPIU before issuing the command */
-ufshcd_compose_upiu(lrbp);
+ufshcd_compose_upiu(hba, lrbp);
 err = ufshcd_map_sg(lrbp);
 if (err)
 goto out;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -677,8 +810,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ufshcd_host_memory_configure(struct ufs_hba *hba)
 cpu_to_le16(ALIGNED_UPIU_SIZE);
 
 hba-&amp;gt;lrb[i].utr_descriptor_ptr = (utrdlp + i);
-hba-&amp;gt;lrb[i].ucd_cmd_ptr =
-(struct utp_upiu_cmd *)(cmd_descp + i);
+hba-&amp;gt;lrb[i].ucd_req_ptr =
+(struct utp_upiu_req *)(cmd_descp + i);
 hba-&amp;gt;lrb[i].ucd_rsp_ptr =
 (struct utp_upiu_rsp *)cmd_descp[i].response_upiu;
 hba-&amp;gt;lrb[i].ucd_prdt_ptr =
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1101,7 +1234,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; ufshcd_scsi_cmd_status(struct ufshcd_lrb *lrbp, int scsi_status)
  * &amp;lt; at &amp;gt;hba: per adapter instance
  * &amp;lt; at &amp;gt;lrb: pointer to local reference block of completed command
  *
- * Returns result of the command to notify SCSI midlayer
+ * Returns result of the command to notify SCSI midlayer. In
+ * case of query request specific result, returns DID_OK, and
+ * the error will be handled by the dispatcher.
  */
 static inline int
 ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1115,27 +1250,46 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
 
 switch (ocs) {
 case OCS_SUCCESS:
-
 /* check if the returned transfer response is valid */
-result = ufshcd_is_valid_req_rsp(lrbp-&amp;gt;ucd_rsp_ptr);
-if (result) {
+result = ufshcd_get_req_rsp(lrbp-&amp;gt;ucd_rsp_ptr);
+
+switch (result) {
+case UPIU_TRANSACTION_RESPONSE:
+/*
+ * get the response UPIU result to extract
+ * the SCSI command status
+ */
+result = ufshcd_get_rsp_upiu_result(lrbp-&amp;gt;ucd_rsp_ptr);
+
+/*
+ * get the result based on SCSI status response
+ * to notify the SCSI midlayer of the command status
+ */
+scsi_status = result &amp;amp; MASK_SCSI_STATUS;
+result = ufshcd_scsi_cmd_status(lrbp, scsi_status);
+break;
+case UPIU_TRANSACTION_QUERY_RSP:
+/*
+ *  Return result = ok, since SCSI layer wouldn't
+ *  know how to handle errors from query requests.
+ *  The result is saved with the response so that
+ *  the ufs_core layer will handle it.
+ */
+result = DID_OK &amp;lt;&amp;lt; 16;
+ufshcd_copy_query_response(hba, lrbp);
+break;
+case UPIU_TRANSACTION_REJECT_UPIU:
+/* TODO: handle Reject UPIU Response */
+result = DID_ERROR &amp;lt;&amp;lt; 16;
 dev_err(hba-&amp;gt;dev,
-"Invalid response = %x\n", result);
+"Reject UPIU not fully implemented\n");
 break;
+default:
+result = DID_ERROR &amp;lt;&amp;lt; 16;
+dev_err(hba-&amp;gt;dev,
+"Unexpected request response code = %x\n",
+result);
 }
-
-/*
- * get the response UPIU result to extract
- * the SCSI command status
- */
-result = ufshcd_get_rsp_upiu_result(lrbp-&amp;gt;ucd_rsp_ptr);
-
-/*
- * get the result based on SCSI status response
- * to notify the SCSI midlayer of the command status
- */
-scsi_status = result &amp;amp; MASK_SCSI_STATUS;
-result = ufshcd_scsi_cmd_status(lrbp, scsi_status);
 break;
 case OCS_ABORTED:
 result |= DID_ABORT &amp;lt;&amp;lt; 16;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1364,10 +1518,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; ufshcd_issue_tm_cmd(struct ufs_hba *hba,
 task_req_upiup =
 (struct utp_upiu_task_req *) task_req_descp-&amp;gt;task_req_upiu;
 task_req_upiup-&amp;gt;header.dword_0 =
-cpu_to_be32(UPIU_HEADER_DWORD(UPIU_TRANSACTION_TASK_REQ, 0,
-      lrbp-&amp;gt;lun, lrbp-&amp;gt;task_tag));
+UPIU_HEADER_DWORD(UPIU_TRANSACTION_TASK_REQ, 0,
+      lrbp-&amp;gt;lun, lrbp-&amp;gt;task_tag);
 task_req_upiup-&amp;gt;header.dword_1 =
-cpu_to_be32(UPIU_HEADER_DWORD(0, tm_function, 0, 0));
+UPIU_HEADER_DWORD(0, tm_function, 0, 0);
 
 task_req_upiup-&amp;gt;input_param1 = lrbp-&amp;gt;lun;
 task_req_upiup-&amp;gt;input_param1 =
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1670,6 +1824,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle,
 INIT_WORK(&amp;amp;hba-&amp;gt;uic_workq, ufshcd_uic_cc_handler);
 INIT_WORK(&amp;amp;hba-&amp;gt;feh_workq, ufshcd_fatal_err_handler);
 
+/* Initialize mutex for query requests */
+mutex_init(&amp;amp;hba-&amp;gt;query.lock_ufs_query);
+
 /* IRQ registration */
 err = request_irq(irq, ufshcd_intr, IRQF_SHARED, UFSHCD, hba);
 if (err) {
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 6b99a42..336980b 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -60,6 +60,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include &amp;lt;scsi/scsi_tcq.h&amp;gt;
 #include &amp;lt;scsi/scsi_dbg.h&amp;gt;
 #include &amp;lt;scsi/scsi_eh.h&amp;gt;
+#include &amp;lt;scsi/scsi_device.h&amp;gt;
 
 #include "ufs.h"
 #include "ufshci.h"
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -88,7 +89,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct uic_command {
 /**
  * struct ufshcd_lrb - local reference block
  * &amp;lt; at &amp;gt;utr_descriptor_ptr: UTRD address of the command
- * &amp;lt; at &amp;gt;ucd_cmd_ptr: UCD address of the command
+ * &amp;lt; at &amp;gt;ucd_req_ptr: UCD address of the command
  * &amp;lt; at &amp;gt;ucd_rsp_ptr: Response UPIU address for this command
  * &amp;lt; at &amp;gt;ucd_prdt_ptr: PRDT address of the command
  * &amp;lt; at &amp;gt;cmd: pointer to SCSI command
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -101,7 +102,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct uic_command {
  */
 struct ufshcd_lrb {
 struct utp_transfer_req_desc *utr_descriptor_ptr;
-struct utp_upiu_cmd *ucd_cmd_ptr;
+struct utp_upiu_req *ucd_req_ptr;
 struct utp_upiu_rsp *ucd_rsp_ptr;
 struct ufshcd_sg_entry *ucd_prdt_ptr;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -115,6 +116,19 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct ufshcd_lrb {
 unsigned int lun;
 };
 
+/**
+ * struct ufs_query - keeps the query request information
+ * &amp;lt; at &amp;gt;request: request upiu and function
+ * &amp;lt; at &amp;gt;descriptor: buffer for sending/receiving descriptor
+ * &amp;lt; at &amp;gt;response: response upiu and response
+ * &amp;lt; at &amp;gt;mutex: lock to allow one query at a time
+ */
+struct ufs_query {
+struct ufs_query_req *request;
+u8 *descriptor;
+struct ufs_query_res *response;
+struct mutex lock_ufs_query;
+};
 
 /**
  * struct ufs_hba - per adapter private structure
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -143,6 +157,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct ufshcd_lrb {
  * &amp;lt; at &amp;gt;uic_workq: Work queue for UIC completion handling
  * &amp;lt; at &amp;gt;feh_workq: Work queue for fatal controller error handling
  * &amp;lt; at &amp;gt;errors: HBA errors
+ * &amp;lt; at &amp;gt;query: query request information
  */
 struct ufs_hba {
 void __iomem *mmio_base;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -184,6 +199,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct ufs_hba {
 
 /* HBA Errors */
 u32 errors;
+
+/* Query Request */
+struct ufs_query query;
 };
 
 int ufshcd_init(struct device *, struct ufs_hba ** , void __iomem * ,
diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h
index 0c16484..4a86247 100644
--- a/drivers/scsi/ufs/ufshci.h
+++ b/drivers/scsi/ufs/ufshci.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -39,7 +39,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 enum {
 TASK_REQ_UPIU_SIZE_DWORDS= 8,
 TASK_RSP_UPIU_SIZE_DWORDS= 8,
-ALIGNED_UPIU_SIZE= 128,
+ALIGNED_UPIU_SIZE= 512,
 };
 
 /* UFSHCI Registers */
&lt;/pre&gt;</description>
    <dc:creator>Santosh Y</dc:creator>
    <dc:date>2013-05-19T08:21:36</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82075">
    <title>[PATCH 0/8] scsi: ufs: query support and other fixes</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82075</link>
    <description>&lt;pre&gt;Hi James,

Please merge the following patches to 'misc' branch.

Thanks,
Santosh

Dolev Raviv (3):
  scsi: ufs: add support for query requests
  scsi: ufs: Add support for sending NOP OUT UPIU
  scsi: ufs: Set fDeviceInit flag to initiate device initialization

Seungwon Jeon (4):
  scsi: ufs: wrap the i/o access operations
  scsi: ufs: amend interrupt configuration
  scsi: ufs: remove version check before IS reg clear
  scsi: ufs: rework link start-up process

Sujit Reddy Thumma (1):
  scsi: ufs: Fix the response UPIU length setting

 drivers/scsi/ufs/ufs.h    |  132 ++++-
 drivers/scsi/ufs/ufshcd.c | 1172 +++++++++++++++++++++++++++++++++++----------
 drivers/scsi/ufs/ufshcd.h |   47 +-
 drivers/scsi/ufs/ufshci.h |    7 +-
 4 files changed, 1085 insertions(+), 273 deletions(-)

&lt;/pre&gt;</description>
    <dc:creator>Santosh Y</dc:creator>
    <dc:date>2013-05-19T08:21:35</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.scsi/82074">
    <title>(unknown)</title>
    <link>http://permalink.gmane.org/gmane.linux.scsi/82074</link>
    <description>&lt;pre&gt;
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo&amp;lt; at &amp;gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>Penki šimtai tūkstančių dolerių buvo suteikta už savo elektroninio pašto ID.</dc:creator>
    <dc:date>2013-05-18T20:59:08</dc:date>
  </item>
  <textinput rdf:about="http://search.gmane.org/?group=$group=gmane.linux.scsi">
    <title>Search Engine</title>
    <description>Search the mailing list at Gmane</description>
    <name>query</name>
    <link>http://search.gmane.org/?group=$group=gmane.linux.scsi</link>
  </textinput>
</rdf:RDF>
