Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Jan 2021 20:58:07 +0000 (12:58 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Jan 2021 20:58:07 +0000 (12:58 -0800)
Pull SCSI fixes from James Bottomley:
 "This is a load of driver fixes (12 ufs, 1 mpt3sas, 1 cxgbi).

  The big core two fixes are for power management ("block: Do not accept
  any requests while suspended" and "block: Fix a race in the runtime
  power management code") which finally sorts out the resume problems
  we've occasionally been having.

  To make the resume fix, there are seven necessary precursors which
  effectively renames REQ_PREEMPT to REQ_PM, so every "special" request
  in block is automatically a power management exempt one.

  All of the non-PM preempt cases are removed except for the one in the
  SCSI Parallel Interface (spi) domain validation which is a genuine
  case where we have to run requests at high priority to validate the
  bus so this becomes an autopm get/put protected request"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (22 commits)
  scsi: cxgb4i: Fix TLS dependency
  scsi: ufs: Un-inline ufshcd_vops_device_reset function
  scsi: ufs: Re-enable WriteBooster after device reset
  scsi: ufs-mediatek: Use correct path to fix compile error
  scsi: mpt3sas: Signedness bug in _base_get_diag_triggers()
  scsi: block: Do not accept any requests while suspended
  scsi: block: Remove RQF_PREEMPT and BLK_MQ_REQ_PREEMPT
  scsi: core: Only process PM requests if rpm_status != RPM_ACTIVE
  scsi: scsi_transport_spi: Set RQF_PM for domain validation commands
  scsi: ide: Mark power management requests with RQF_PM instead of RQF_PREEMPT
  scsi: ide: Do not set the RQF_PREEMPT flag for sense requests
  scsi: block: Introduce BLK_MQ_REQ_PM
  scsi: block: Fix a race in the runtime power management code
  scsi: ufs-pci: Enable UFSHCD_CAP_RPM_AUTOSUSPEND for Intel controllers
  scsi: ufs-pci: Fix recovery from hibernate exit errors for Intel controllers
  scsi: ufs-pci: Ensure UFS device is in PowerDown mode for suspend-to-disk ->poweroff()
  scsi: ufs-pci: Fix restore from S4 for Intel controllers
  scsi: ufs-mediatek: Keep VCC always-on for specific devices
  scsi: ufs: Allow regulators being always-on
  scsi: ufs: Clear UAC for RPMB after ufshcd resets
  ...

1  2 
block/blk-core.c
block/blk-mq-debugfs.c
block/blk-mq.c
drivers/scsi/mpt3sas/mpt3sas_base.c
drivers/scsi/scsi_lib.c
drivers/scsi/ufs/ufshcd.c
drivers/scsi/ufs/ufshcd.h
include/linux/blk-mq.h
include/linux/blkdev.h

diff --combined block/blk-core.c
@@@ -18,6 -18,7 +18,7 @@@
  #include <linux/bio.h>
  #include <linux/blkdev.h>
  #include <linux/blk-mq.h>
+ #include <linux/blk-pm.h>
  #include <linux/highmem.h>
  #include <linux/mm.h>
  #include <linux/pagemap.h>
@@@ -424,11 -425,11 +425,11 @@@ EXPORT_SYMBOL(blk_cleanup_queue)
  /**
   * blk_queue_enter() - try to increase q->q_usage_counter
   * @q: request queue pointer
-  * @flags: BLK_MQ_REQ_NOWAIT and/or BLK_MQ_REQ_PREEMPT
+  * @flags: BLK_MQ_REQ_NOWAIT and/or BLK_MQ_REQ_PM
   */
  int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags)
  {
-       const bool pm = flags & BLK_MQ_REQ_PREEMPT;
+       const bool pm = flags & BLK_MQ_REQ_PM;
  
        while (true) {
                bool success = false;
                         * responsible for ensuring that that counter is
                         * globally visible before the queue is unfrozen.
                         */
-                       if (pm || !blk_queue_pm_only(q)) {
+                       if ((pm && queue_rpm_status(q) != RPM_SUSPENDED) ||
+                           !blk_queue_pm_only(q)) {
                                success = true;
                        } else {
                                percpu_ref_put(&q->q_usage_counter);
  
                wait_event(q->mq_freeze_wq,
                           (!q->mq_freeze_depth &&
-                           (pm || (blk_pm_request_resume(q),
-                                   !blk_queue_pm_only(q)))) ||
+                           blk_pm_resume_queue(pm, q)) ||
                           blk_queue_dying(q));
                if (blk_queue_dying(q))
                        return -ENODEV;
@@@ -630,7 -631,7 +631,7 @@@ struct request *blk_get_request(struct 
        struct request *req;
  
        WARN_ON_ONCE(op & REQ_NOWAIT);
-       WARN_ON_ONCE(flags & ~(BLK_MQ_REQ_NOWAIT | BLK_MQ_REQ_PREEMPT));
+       WARN_ON_ONCE(flags & ~(BLK_MQ_REQ_NOWAIT | BLK_MQ_REQ_PM));
  
        req = blk_mq_alloc_request(q, op, flags);
        if (!IS_ERR(req) && q->mq_ops->initialize_rq_fn)
@@@ -666,9 -667,9 +667,9 @@@ static int __init setup_fail_make_reque
  }
  __setup("fail_make_request=", setup_fail_make_request);
  
 -static bool should_fail_request(struct hd_struct *part, unsigned int bytes)
 +static bool should_fail_request(struct block_device *part, unsigned int bytes)
  {
 -      return part->make_it_fail && should_fail(&fail_make_request, bytes);
 +      return part->bd_make_it_fail && should_fail(&fail_make_request, bytes);
  }
  
  static int __init fail_make_request_debugfs(void)
@@@ -683,7 -684,7 +684,7 @@@ late_initcall(fail_make_request_debugfs
  
  #else /* CONFIG_FAIL_MAKE_REQUEST */
  
 -static inline bool should_fail_request(struct hd_struct *part,
 +static inline bool should_fail_request(struct block_device *part,
                                        unsigned int bytes)
  {
        return false;
  
  #endif /* CONFIG_FAIL_MAKE_REQUEST */
  
 -static inline bool bio_check_ro(struct bio *bio, struct hd_struct *part)
 +static inline bool bio_check_ro(struct bio *bio, struct block_device *part)
  {
        const int op = bio_op(bio);
  
 -      if (part->policy && op_is_write(op)) {
 +      if (part->bd_read_only && op_is_write(op)) {
                char b[BDEVNAME_SIZE];
  
                if (op_is_flush(bio->bi_opf) && !bio_sectors(bio))
  
                WARN_ONCE(1,
                       "Trying to write to read-only block-device %s (partno %d)\n",
 -                      bio_devname(bio, b), part->partno);
 +                      bio_devname(bio, b), part->bd_partno);
                /* Older lvm-tools actually trigger this */
                return false;
        }
  
  static noinline int should_fail_bio(struct bio *bio)
  {
 -      if (should_fail_request(&bio->bi_disk->part0, bio->bi_iter.bi_size))
 +      if (should_fail_request(bio->bi_disk->part0, bio->bi_iter.bi_size))
                return -EIO;
        return 0;
  }
@@@ -742,7 -743,7 +743,7 @@@ static inline int bio_check_eod(struct 
   */
  static inline int blk_partition_remap(struct bio *bio)
  {
 -      struct hd_struct *p;
 +      struct block_device *p;
        int ret = -EIO;
  
        rcu_read_lock();
                goto out;
  
        if (bio_sectors(bio)) {
 -              if (bio_check_eod(bio, part_nr_sects_read(p)))
 +              if (bio_check_eod(bio, bdev_nr_sectors(p)))
                        goto out;
 -              bio->bi_iter.bi_sector += p->start_sect;
 -              trace_block_bio_remap(bio->bi_disk->queue, bio, part_devt(p),
 -                                    bio->bi_iter.bi_sector - p->start_sect);
 +              bio->bi_iter.bi_sector += p->bd_start_sect;
 +              trace_block_bio_remap(bio, p->bd_dev,
 +                                    bio->bi_iter.bi_sector -
 +                                    p->bd_start_sect);
        }
        bio->bi_partno = 0;
        ret = 0;
@@@ -830,7 -830,7 +831,7 @@@ static noinline_for_stack bool submit_b
                if (unlikely(blk_partition_remap(bio)))
                        goto end_io;
        } else {
 -              if (unlikely(bio_check_ro(bio, &bio->bi_disk->part0)))
 +              if (unlikely(bio_check_ro(bio, bio->bi_disk->part0)))
                        goto end_io;
                if (unlikely(bio_check_eod(bio, get_capacity(bio->bi_disk))))
                        goto end_io;
        blkcg_bio_issue_init(bio);
  
        if (!bio_flagged(bio, BIO_TRACE_COMPLETION)) {
 -              trace_block_bio_queue(q, bio);
 +              trace_block_bio_queue(bio);
                /* Now that enqueuing has been traced, we need to trace
                 * completion as well.
                 */
@@@ -1202,7 -1202,7 +1203,7 @@@ blk_status_t blk_insert_cloned_request(
                return ret;
  
        if (rq->rq_disk &&
 -          should_fail_request(&rq->rq_disk->part0, blk_rq_bytes(rq)))
 +          should_fail_request(rq->rq_disk->part0, blk_rq_bytes(rq)))
                return BLK_STS_IOERR;
  
        if (blk_crypto_insert_cloned_request(rq))
@@@ -1261,18 -1261,17 +1262,18 @@@ unsigned int blk_rq_err_bytes(const str
  }
  EXPORT_SYMBOL_GPL(blk_rq_err_bytes);
  
 -static void update_io_ticks(struct hd_struct *part, unsigned long now, bool end)
 +static void update_io_ticks(struct block_device *part, unsigned long now,
 +              bool end)
  {
        unsigned long stamp;
  again:
 -      stamp = READ_ONCE(part->stamp);
 +      stamp = READ_ONCE(part->bd_stamp);
        if (unlikely(stamp != now)) {
 -              if (likely(cmpxchg(&part->stamp, stamp, now) == stamp))
 +              if (likely(cmpxchg(&part->bd_stamp, stamp, now) == stamp))
                        __part_stat_add(part, io_ticks, end ? now - stamp : 1);
        }
 -      if (part->partno) {
 -              part = &part_to_disk(part)->part0;
 +      if (part->bd_partno) {
 +              part = bdev_whole(part);
                goto again;
        }
  }
@@@ -1281,9 -1280,11 +1282,9 @@@ static void blk_account_io_completion(s
  {
        if (req->part && blk_do_io_stat(req)) {
                const int sgrp = op_stat_group(req_op(req));
 -              struct hd_struct *part;
  
                part_stat_lock();
 -              part = req->part;
 -              part_stat_add(part, sectors[sgrp], bytes >> 9);
 +              part_stat_add(req->part, sectors[sgrp], bytes >> 9);
                part_stat_unlock();
        }
  }
@@@ -1298,12 -1299,17 +1299,12 @@@ void blk_account_io_done(struct reques
        if (req->part && blk_do_io_stat(req) &&
            !(req->rq_flags & RQF_FLUSH_SEQ)) {
                const int sgrp = op_stat_group(req_op(req));
 -              struct hd_struct *part;
  
                part_stat_lock();
 -              part = req->part;
 -
 -              update_io_ticks(part, jiffies, true);
 -              part_stat_inc(part, ios[sgrp]);
 -              part_stat_add(part, nsecs[sgrp], now - req->start_time_ns);
 +              update_io_ticks(req->part, jiffies, true);
 +              part_stat_inc(req->part, ios[sgrp]);
 +              part_stat_add(req->part, nsecs[sgrp], now - req->start_time_ns);
                part_stat_unlock();
 -
 -              hd_struct_put(part);
        }
  }
  
@@@ -1319,7 -1325,7 +1320,7 @@@ void blk_account_io_start(struct reques
        part_stat_unlock();
  }
  
 -static unsigned long __part_start_io_acct(struct hd_struct *part,
 +static unsigned long __part_start_io_acct(struct block_device *part,
                                          unsigned int sectors, unsigned int op)
  {
        const int sgrp = op_stat_group(op);
        return now;
  }
  
 -unsigned long part_start_io_acct(struct gendisk *disk, struct hd_struct **part,
 +unsigned long part_start_io_acct(struct gendisk *disk, struct block_device **part,
                                 struct bio *bio)
  {
        *part = disk_map_sector_rcu(disk, bio->bi_iter.bi_sector);
@@@ -1347,11 -1353,11 +1348,11 @@@ EXPORT_SYMBOL_GPL(part_start_io_acct)
  unsigned long disk_start_io_acct(struct gendisk *disk, unsigned int sectors,
                                 unsigned int op)
  {
 -      return __part_start_io_acct(&disk->part0, sectors, op);
 +      return __part_start_io_acct(disk->part0, sectors, op);
  }
  EXPORT_SYMBOL(disk_start_io_acct);
  
 -static void __part_end_io_acct(struct hd_struct *part, unsigned int op,
 +static void __part_end_io_acct(struct block_device *part, unsigned int op,
                               unsigned long start_time)
  {
        const int sgrp = op_stat_group(op);
        part_stat_unlock();
  }
  
 -void part_end_io_acct(struct hd_struct *part, struct bio *bio,
 +void part_end_io_acct(struct block_device *part, struct bio *bio,
                      unsigned long start_time)
  {
        __part_end_io_acct(part, bio_op(bio), start_time);
 -      hd_struct_put(part);
  }
  EXPORT_SYMBOL_GPL(part_end_io_acct);
  
  void disk_end_io_acct(struct gendisk *disk, unsigned int op,
                      unsigned long start_time)
  {
 -      __part_end_io_acct(&disk->part0, op, start_time);
 +      __part_end_io_acct(disk->part0, op, start_time);
  }
  EXPORT_SYMBOL(disk_end_io_acct);
  
diff --combined block/blk-mq-debugfs.c
@@@ -129,7 -129,6 +129,7 @@@ static const char *const blk_queue_flag
        QUEUE_FLAG_NAME(PCI_P2PDMA),
        QUEUE_FLAG_NAME(ZONE_RESETALL),
        QUEUE_FLAG_NAME(RQ_ALLOC_TIME),
 +      QUEUE_FLAG_NAME(NOWAIT),
  };
  #undef QUEUE_FLAG_NAME
  
@@@ -298,7 -297,6 +298,6 @@@ static const char *const rqf_name[] = 
        RQF_NAME(MIXED_MERGE),
        RQF_NAME(MQ_INFLIGHT),
        RQF_NAME(DONTPREP),
-       RQF_NAME(PREEMPT),
        RQF_NAME(FAILED),
        RQF_NAME(QUIET),
        RQF_NAME(ELVPRIV),
diff --combined block/blk-mq.c
@@@ -95,7 -95,7 +95,7 @@@ static void blk_mq_hctx_clear_pending(s
  }
  
  struct mq_inflight {
 -      struct hd_struct *part;
 +      struct block_device *part;
        unsigned int inflight[2];
  };
  
@@@ -105,15 -105,13 +105,15 @@@ static bool blk_mq_check_inflight(struc
  {
        struct mq_inflight *mi = priv;
  
 -      if (rq->part == mi->part && blk_mq_rq_state(rq) == MQ_RQ_IN_FLIGHT)
 +      if ((!mi->part->bd_partno || rq->part == mi->part) &&
 +          blk_mq_rq_state(rq) == MQ_RQ_IN_FLIGHT)
                mi->inflight[rq_data_dir(rq)]++;
  
        return true;
  }
  
 -unsigned int blk_mq_in_flight(struct request_queue *q, struct hd_struct *part)
 +unsigned int blk_mq_in_flight(struct request_queue *q,
 +              struct block_device *part)
  {
        struct mq_inflight mi = { .part = part };
  
        return mi.inflight[0] + mi.inflight[1];
  }
  
 -void blk_mq_in_flight_rw(struct request_queue *q, struct hd_struct *part,
 -                       unsigned int inflight[2])
 +void blk_mq_in_flight_rw(struct request_queue *q, struct block_device *part,
 +              unsigned int inflight[2])
  {
        struct mq_inflight mi = { .part = part };
  
@@@ -294,8 -292,8 +294,8 @@@ static struct request *blk_mq_rq_ctx_in
        rq->mq_hctx = data->hctx;
        rq->rq_flags = 0;
        rq->cmd_flags = data->cmd_flags;
-       if (data->flags & BLK_MQ_REQ_PREEMPT)
-               rq->rq_flags |= RQF_PREEMPT;
+       if (data->flags & BLK_MQ_REQ_PM)
+               rq->rq_flags |= RQF_PM;
        if (blk_queue_io_stat(data->q))
                rq->rq_flags |= RQF_IO_STAT;
        INIT_LIST_HEAD(&rq->queuelist);
@@@ -650,14 -648,6 +650,14 @@@ static inline bool blk_mq_complete_need
        if (!IS_ENABLED(CONFIG_SMP) ||
            !test_bit(QUEUE_FLAG_SAME_COMP, &rq->q->queue_flags))
                return false;
 +      /*
 +       * With force threaded interrupts enabled, raising softirq from an SMP
 +       * function call will always result in waking the ksoftirqd thread.
 +       * This is probably worse than completing the request on a different
 +       * cache domain.
 +       */
 +      if (force_irqthreads)
 +              return false;
  
        /* same CPU or cache domain?  Complete locally */
        if (cpu == rq->mq_ctx->cpu ||
@@@ -681,7 -671,9 +681,7 @@@ bool blk_mq_complete_request_remote(str
                return false;
  
        if (blk_mq_complete_need_ipi(rq)) {
 -              rq->csd.func = __blk_mq_complete_request_remote;
 -              rq->csd.info = rq;
 -              rq->csd.flags = 0;
 +              INIT_CSD(&rq->csd, __blk_mq_complete_request_remote, rq);
                smp_call_function_single_async(rq->mq_ctx->cpu, &rq->csd);
        } else {
                if (rq->q->nr_hw_queues > 1)
@@@ -739,7 -731,7 +739,7 @@@ void blk_mq_start_request(struct reques
  {
        struct request_queue *q = rq->q;
  
 -      trace_block_rq_issue(q, rq);
 +      trace_block_rq_issue(rq);
  
        if (test_bit(QUEUE_FLAG_STATS, &q->queue_flags)) {
                rq->io_start_time_ns = ktime_get_ns();
@@@ -766,7 -758,7 +766,7 @@@ static void __blk_mq_requeue_request(st
  
        blk_mq_put_driver_tag(rq);
  
 -      trace_block_rq_requeue(q, rq);
 +      trace_block_rq_requeue(rq);
        rq_qos_requeue(q, rq);
  
        if (blk_mq_request_started(rq)) {
@@@ -1503,6 -1495,31 +1503,6 @@@ static void __blk_mq_run_hw_queue(struc
  {
        int srcu_idx;
  
 -      /*
 -       * We should be running this queue from one of the CPUs that
 -       * are mapped to it.
 -       *
 -       * There are at least two related races now between setting
 -       * hctx->next_cpu from blk_mq_hctx_next_cpu() and running
 -       * __blk_mq_run_hw_queue():
 -       *
 -       * - hctx->next_cpu is found offline in blk_mq_hctx_next_cpu(),
 -       *   but later it becomes online, then this warning is harmless
 -       *   at all
 -       *
 -       * - hctx->next_cpu is found online in blk_mq_hctx_next_cpu(),
 -       *   but later it becomes offline, then the warning can't be
 -       *   triggered, and we depend on blk-mq timeout handler to
 -       *   handle dispatched requests to this hctx
 -       */
 -      if (!cpumask_test_cpu(raw_smp_processor_id(), hctx->cpumask) &&
 -              cpu_online(hctx->next_cpu)) {
 -              printk(KERN_WARNING "run queue from wrong CPU %d, hctx %s\n",
 -                      raw_smp_processor_id(),
 -                      cpumask_empty(hctx->cpumask) ? "inactive": "active");
 -              dump_stack();
 -      }
 -
        /*
         * We can't run the queue inline with ints disabled. Ensure that
         * we catch bad users of this early.
@@@ -1575,7 -1592,7 +1575,7 @@@ select_cpu
   * __blk_mq_delay_run_hw_queue - Run (or schedule to run) a hardware queue.
   * @hctx: Pointer to the hardware queue to run.
   * @async: If we want to run the queue asynchronously.
 - * @msecs: Microseconds of delay to wait before running the queue.
 + * @msecs: Milliseconds of delay to wait before running the queue.
   *
   * If !@async, try to run the queue now. Else, run the queue asynchronously and
   * with a delay of @msecs.
@@@ -1604,7 -1621,7 +1604,7 @@@ static void __blk_mq_delay_run_hw_queue
  /**
   * blk_mq_delay_run_hw_queue - Run a hardware queue asynchronously.
   * @hctx: Pointer to the hardware queue to run.
 - * @msecs: Microseconds of delay to wait before running the queue.
 + * @msecs: Milliseconds of delay to wait before running the queue.
   *
   * Run a hardware queue asynchronously with a delay of @msecs.
   */
@@@ -1668,7 -1685,7 +1668,7 @@@ EXPORT_SYMBOL(blk_mq_run_hw_queues)
  /**
   * blk_mq_delay_run_hw_queues - Run all hardware queues asynchronously.
   * @q: Pointer to the request queue to run.
 - * @msecs: Microseconds of delay to wait before running the queues.
 + * @msecs: Milliseconds of delay to wait before running the queues.
   */
  void blk_mq_delay_run_hw_queues(struct request_queue *q, unsigned long msecs)
  {
@@@ -1802,7 -1819,7 +1802,7 @@@ static inline void __blk_mq_insert_req_
  
        lockdep_assert_held(&ctx->lock);
  
 -      trace_block_rq_insert(hctx->queue, rq);
 +      trace_block_rq_insert(rq);
  
        if (at_head)
                list_add(&rq->queuelist, &ctx->rq_lists[type]);
@@@ -1859,7 -1876,7 +1859,7 @@@ void blk_mq_insert_requests(struct blk_
         */
        list_for_each_entry(rq, list, queuelist) {
                BUG_ON(rq->mq_ctx != ctx);
 -              trace_block_rq_insert(hctx->queue, rq);
 +              trace_block_rq_insert(rq);
        }
  
        spin_lock(&ctx->lock);
@@@ -2140,7 -2157,6 +2140,7 @@@ blk_qc_t blk_mq_submit_bio(struct bio *
        unsigned int nr_segs;
        blk_qc_t cookie;
        blk_status_t ret;
 +      bool hipri;
  
        blk_queue_bounce(q, &bio);
        __blk_queue_split(&bio, &nr_segs);
  
        rq_qos_throttle(q, bio);
  
 +      hipri = bio->bi_opf & REQ_HIPRI;
 +
        data.cmd_flags = bio->bi_opf;
        rq = __blk_mq_alloc_request(&data);
        if (unlikely(!rq)) {
                goto queue_exit;
        }
  
 -      trace_block_getrq(q, bio, bio->bi_opf);
 +      trace_block_getrq(bio);
  
        rq_qos_track(q, rq, bio);
  
                blk_mq_sched_insert_request(rq, false, true, true);
        }
  
 +      if (!hipri)
 +              return BLK_QC_T_NONE;
        return cookie;
  queue_exit:
        blk_queue_exit(q);
@@@ -3363,12 -3375,6 +3363,12 @@@ static int blk_mq_realloc_tag_set_tags(
        return 0;
  }
  
 +static int blk_mq_alloc_tag_set_tags(struct blk_mq_tag_set *set,
 +                              int new_nr_hw_queues)
 +{
 +      return blk_mq_realloc_tag_set_tags(set, 0, new_nr_hw_queues);
 +}
 +
  /*
   * Alloc a tag set to be associated with one or more request queues.
   * May fail with EINVAL for various error conditions. May adjust the
@@@ -3422,7 -3428,7 +3422,7 @@@ int blk_mq_alloc_tag_set(struct blk_mq_
        if (set->nr_maps == 1 && set->nr_hw_queues > nr_cpu_ids)
                set->nr_hw_queues = nr_cpu_ids;
  
 -      if (blk_mq_realloc_tag_set_tags(set, 0, set->nr_hw_queues) < 0)
 +      if (blk_mq_alloc_tag_set_tags(set, set->nr_hw_queues) < 0)
                return -ENOMEM;
  
        ret = -ENOMEM;
@@@ -3857,10 -3863,9 +3857,10 @@@ int blk_poll(struct request_queue *q, b
         * the state. Like for the other success return cases, the
         * caller is responsible for checking if the IO completed. If
         * the IO isn't complete, we'll get called again and will go
 -       * straight to the busy poll loop.
 +       * straight to the busy poll loop. If specified not to spin,
 +       * we also should not sleep.
         */
 -      if (blk_mq_poll_hybrid(q, hctx, cookie))
 +      if (spin && blk_mq_poll_hybrid(q, hctx, cookie))
                return 1;
  
        hctx->poll_considered++;
@@@ -1824,13 -1824,6 +1824,13 @@@ _base_irqpoll(struct irq_poll *irqpoll
                reply_q->irq_poll_scheduled = false;
                reply_q->irq_line_enable = true;
                enable_irq(reply_q->os_irq);
 +              /*
 +               * Go for one more round of processing the
 +               * reply descriptor post queue incase if HBA
 +               * Firmware has posted some reply descriptors
 +               * while reenabling the IRQ.
 +               */
 +              _base_process_reply_queue(reply_q);
        }
  
        return num_entries;
@@@ -5034,7 -5027,7 +5034,7 @@@ _base_check_for_trigger_pages_support(s
  static void
  _base_get_diag_triggers(struct MPT3SAS_ADAPTER *ioc)
  {
-       u16 trigger_flags;
+       int trigger_flags;
  
        /*
         * Default setting of master trigger.
@@@ -6888,7 -6881,7 +6888,7 @@@ _base_send_ioc_init(struct MPT3SAS_ADAP
  
        r = _base_handshake_req_reply_wait(ioc,
            sizeof(Mpi2IOCInitRequest_t), (u32 *)&mpi_request,
 -          sizeof(Mpi2IOCInitReply_t), (u16 *)&mpi_reply, 10);
 +          sizeof(Mpi2IOCInitReply_t), (u16 *)&mpi_reply, 30);
  
        if (r != 0) {
                ioc_err(ioc, "%s: handshake failed (r=%d)\n", __func__, r);
diff --combined drivers/scsi/scsi_lib.c
@@@ -249,7 -249,8 +249,8 @@@ int __scsi_execute(struct scsi_device *
  
        req = blk_get_request(sdev->request_queue,
                        data_direction == DMA_TO_DEVICE ?
-                       REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, BLK_MQ_REQ_PREEMPT);
+                       REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN,
+                       rq_flags & RQF_PM ? BLK_MQ_REQ_PM : 0);
        if (IS_ERR(req))
                return ret;
        rq = scsi_req(req);
@@@ -1206,6 -1207,8 +1207,8 @@@ static blk_status_
  scsi_device_state_check(struct scsi_device *sdev, struct request *req)
  {
        switch (sdev->sdev_state) {
+       case SDEV_CREATED:
+               return BLK_STS_OK;
        case SDEV_OFFLINE:
        case SDEV_TRANSPORT_OFFLINE:
                /*
                return BLK_STS_RESOURCE;
        case SDEV_QUIESCE:
                /*
-                * If the devices is blocked we defer normal commands.
+                * If the device is blocked we only accept power management
+                * commands.
                 */
-               if (req && !(req->rq_flags & RQF_PREEMPT))
+               if (req && WARN_ON_ONCE(!(req->rq_flags & RQF_PM)))
                        return BLK_STS_RESOURCE;
                return BLK_STS_OK;
        default:
                /*
                 * For any other not fully online state we only allow
-                * special commands.  In particular any user initiated
-                * command is not allowed.
+                * power management commands.
                 */
-               if (req && !(req->rq_flags & RQF_PREEMPT))
+               if (req && !(req->rq_flags & RQF_PM))
                        return BLK_STS_IOERR;
                return BLK_STS_OK;
        }
@@@ -1706,7 -1709,8 +1709,7 @@@ out_put_budget
                break;
        case BLK_STS_RESOURCE:
        case BLK_STS_ZONE_RESOURCE:
 -              if (atomic_read(&sdev->device_busy) ||
 -                  scsi_device_blocked(sdev))
 +              if (scsi_device_blocked(sdev))
                        ret = BLK_STS_DEV_RESOURCE;
                break;
        case BLK_STS_AGAIN:
@@@ -2516,15 -2520,13 +2519,13 @@@ void sdev_evt_send_simple(struct scsi_d
  EXPORT_SYMBOL_GPL(sdev_evt_send_simple);
  
  /**
-  *    scsi_device_quiesce - Block user issued commands.
+  *    scsi_device_quiesce - Block all commands except power management.
   *    @sdev:  scsi device to quiesce.
   *
   *    This works by trying to transition to the SDEV_QUIESCE state
   *    (which must be a legal transition).  When the device is in this
-  *    state, only special requests will be accepted, all others will
-  *    be deferred.  Since special requests may also be requeued requests,
-  *    a successful return doesn't guarantee the device will be
-  *    totally quiescent.
+  *    state, only power management requests will be accepted, all others will
+  *    be deferred.
   *
   *    Must be called with user context, may sleep.
   *
@@@ -2586,12 -2588,12 +2587,12 @@@ void scsi_device_resume(struct scsi_dev
         * device deleted during suspend)
         */
        mutex_lock(&sdev->state_mutex);
+       if (sdev->sdev_state == SDEV_QUIESCE)
+               scsi_device_set_state(sdev, SDEV_RUNNING);
        if (sdev->quiesced_by) {
                sdev->quiesced_by = NULL;
                blk_clear_pm_only(sdev->request_queue);
        }
-       if (sdev->sdev_state == SDEV_QUIESCE)
-               scsi_device_set_state(sdev, SDEV_RUNNING);
        mutex_unlock(&sdev->state_mutex);
  }
  EXPORT_SYMBOL(scsi_device_resume);
@@@ -225,6 -225,7 +225,7 @@@ static int ufshcd_reset_and_restore(str
  static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd);
  static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag);
  static void ufshcd_hba_exit(struct ufs_hba *hba);
+ static int ufshcd_clear_ua_wluns(struct ufs_hba *hba);
  static int ufshcd_probe_hba(struct ufs_hba *hba, bool async);
  static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on);
  static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba);
@@@ -580,6 -581,23 +581,23 @@@ static void ufshcd_print_pwr_info(struc
                 hba->pwr_info.hs_rate);
  }
  
+ static void ufshcd_device_reset(struct ufs_hba *hba)
+ {
+       int err;
+       err = ufshcd_vops_device_reset(hba);
+       if (!err) {
+               ufshcd_set_ufs_dev_active(hba);
+               if (ufshcd_is_wb_allowed(hba)) {
+                       hba->wb_enabled = false;
+                       hba->wb_buf_flush_enabled = false;
+               }
+       }
+       if (err != -EOPNOTSUPP)
+               ufshcd_update_evt_hist(hba, UFS_EVT_DEV_RESET, err);
+ }
  void ufshcd_delay_us(unsigned long us, unsigned long tolerance)
  {
        if (!us)
@@@ -1310,15 -1328,8 +1328,15 @@@ static int ufshcd_devfreq_target(struc
        }
        spin_unlock_irqrestore(hba->host->host_lock, irq_flags);
  
 +      pm_runtime_get_noresume(hba->dev);
 +      if (!pm_runtime_active(hba->dev)) {
 +              pm_runtime_put_noidle(hba->dev);
 +              ret = -EAGAIN;
 +              goto out;
 +      }
        start = ktime_get();
        ret = ufshcd_devfreq_scale(hba, scale_up);
 +      pm_runtime_put(hba->dev);
  
        trace_ufshcd_profile_clk_scaling(dev_name(hba->dev),
                (scale_up ? "up" : "down"),
@@@ -1651,12 -1662,12 +1669,12 @@@ start
                 */
                fallthrough;
        case CLKS_OFF:
 -              ufshcd_scsi_block_requests(hba);
                hba->clk_gating.state = REQ_CLKS_ON;
                trace_ufshcd_clk_gating(dev_name(hba->dev),
                                        hba->clk_gating.state);
 -              queue_work(hba->clk_gating.clk_gating_workq,
 -                         &hba->clk_gating.ungate_work);
 +              if (queue_work(hba->clk_gating.clk_gating_workq,
 +                             &hba->clk_gating.ungate_work))
 +                      ufshcd_scsi_block_requests(hba);
                /*
                 * fall through to check if we should wait for this
                 * work to be done or not.
@@@ -2141,20 -2152,10 +2159,20 @@@ ufshcd_wait_for_uic_cmd(struct ufs_hba 
        unsigned long flags;
  
        if (wait_for_completion_timeout(&uic_cmd->done,
 -                                      msecs_to_jiffies(UIC_CMD_TIMEOUT)))
 +                                      msecs_to_jiffies(UIC_CMD_TIMEOUT))) {
                ret = uic_cmd->argument2 & MASK_UIC_COMMAND_RESULT;
 -      else
 +      } else {
                ret = -ETIMEDOUT;
 +              dev_err(hba->dev,
 +                      "uic cmd 0x%x with arg3 0x%x completion timeout\n",
 +                      uic_cmd->command, uic_cmd->argument3);
 +
 +              if (!uic_cmd->cmd_active) {
 +                      dev_err(hba->dev, "%s: UIC cmd has been completed, return the result\n",
 +                              __func__);
 +                      ret = uic_cmd->argument2 & MASK_UIC_COMMAND_RESULT;
 +              }
 +      }
  
        spin_lock_irqsave(hba->host->host_lock, flags);
        hba->active_uic_cmd = NULL;
@@@ -2186,7 -2187,6 +2204,7 @@@ __ufshcd_send_uic_cmd(struct ufs_hba *h
        if (completion)
                init_completion(&uic_cmd->done);
  
 +      uic_cmd->cmd_active = 1;
        ufshcd_dispatch_uic_cmd(hba, uic_cmd);
  
        return 0;
@@@ -3229,19 -3229,13 +3247,19 @@@ int ufshcd_read_desc_param(struct ufs_h
        /* Get the length of descriptor */
        ufshcd_map_desc_id_to_length(hba, desc_id, &buff_len);
        if (!buff_len) {
 -              dev_err(hba->dev, "%s: Failed to get desc length", __func__);
 +              dev_err(hba->dev, "%s: Failed to get desc length\n", __func__);
 +              return -EINVAL;
 +      }
 +
 +      if (param_offset >= buff_len) {
 +              dev_err(hba->dev, "%s: Invalid offset 0x%x in descriptor IDN 0x%x, length 0x%x\n",
 +                      __func__, param_offset, desc_id, buff_len);
                return -EINVAL;
        }
  
        /* Check whether we need temp memory */
        if (param_offset != 0 || param_size < buff_len) {
 -              desc_buf = kmalloc(buff_len, GFP_KERNEL);
 +              desc_buf = kzalloc(buff_len, GFP_KERNEL);
                if (!desc_buf)
                        return -ENOMEM;
        } else {
                                        desc_buf, &buff_len);
  
        if (ret) {
 -              dev_err(hba->dev, "%s: Failed reading descriptor. desc_id %d, desc_index %d, param_offset %d, ret %d",
 +              dev_err(hba->dev, "%s: Failed reading descriptor. desc_id %d, desc_index %d, param_offset %d, ret %d\n",
                        __func__, desc_id, desc_index, param_offset, ret);
                goto out;
        }
  
        /* Sanity check */
        if (desc_buf[QUERY_DESC_DESC_TYPE_OFFSET] != desc_id) {
 -              dev_err(hba->dev, "%s: invalid desc_id %d in descriptor header",
 +              dev_err(hba->dev, "%s: invalid desc_id %d in descriptor header\n",
                        __func__, desc_buf[QUERY_DESC_DESC_TYPE_OFFSET]);
                ret = -EINVAL;
                goto out;
        buff_len = desc_buf[QUERY_DESC_LENGTH_OFFSET];
        ufshcd_update_desc_length(hba, desc_id, desc_index, buff_len);
  
 -      /* Check wherher we will not copy more data, than available */
 -      if (is_kmalloc && (param_offset + param_size) > buff_len)
 -              param_size = buff_len - param_offset;
 -
 -      if (is_kmalloc)
 +      if (is_kmalloc) {
 +              /* Make sure we don't copy more data than available */
 +              if (param_offset + param_size > buff_len)
 +                      param_size = buff_len - param_offset;
                memcpy(param_read_buf, &desc_buf[param_offset], param_size);
 +      }
  out:
        if (is_kmalloc)
                kfree(desc_buf);
@@@ -3665,7 -3659,7 +3683,7 @@@ static int ufshcd_dme_enable(struct ufs
        ret = ufshcd_send_uic_cmd(hba, &uic_cmd);
        if (ret)
                dev_err(hba->dev,
-                       "dme-reset: error code %d\n", ret);
+                       "dme-enable: error code %d\n", ret);
  
        return ret;
  }
@@@ -3877,18 -3871,10 +3895,18 @@@ static int ufshcd_uic_pwr_ctrl(struct u
                dev_err(hba->dev,
                        "pwr ctrl cmd 0x%x with mode 0x%x completion timeout\n",
                        cmd->command, cmd->argument3);
 +
 +              if (!cmd->cmd_active) {
 +                      dev_err(hba->dev, "%s: Power Mode Change operation has been completed, go check UPMCRS\n",
 +                              __func__);
 +                      goto check_upmcrs;
 +              }
 +
                ret = -ETIMEDOUT;
                goto out;
        }
  
 +check_upmcrs:
        status = ufshcd_get_upmcrs(hba);
        if (status != PWR_LOCAL) {
                dev_err(hba->dev,
@@@ -3964,7 -3950,7 +3982,7 @@@ int ufshcd_link_recovery(struct ufs_hb
        spin_unlock_irqrestore(hba->host->host_lock, flags);
  
        /* Reset the attached device */
-       ufshcd_vops_device_reset(hba);
+       ufshcd_device_reset(hba);
  
        ret = ufshcd_host_reset_and_restore(hba);
  
@@@ -4996,14 -4982,11 +5014,14 @@@ static irqreturn_t ufshcd_uic_cmd_compl
                        ufshcd_get_uic_cmd_result(hba);
                hba->active_uic_cmd->argument3 =
                        ufshcd_get_dme_attr_val(hba);
 +              if (!hba->uic_async_done)
 +                      hba->active_uic_cmd->cmd_active = 0;
                complete(&hba->active_uic_cmd->done);
                retval = IRQ_HANDLED;
        }
  
        if ((intr_status & UFSHCD_UIC_PWR_MASK) && hba->uic_async_done) {
 +              hba->active_uic_cmd->cmd_active = 0;
                complete(hba->uic_async_done);
                retval = IRQ_HANDLED;
        }
@@@ -6930,7 -6913,8 +6948,8 @@@ static int ufshcd_host_reset_and_restor
  
        /* Establish the link again and restore the device */
        err = ufshcd_probe_hba(hba, false);
+       if (!err)
+               ufshcd_clear_ua_wluns(hba);
  out:
        if (err)
                dev_err(hba->dev, "%s: Host init failed %d\n", __func__, err);
@@@ -6968,7 -6952,7 +6987,7 @@@ static int ufshcd_reset_and_restore(str
  
        do {
                /* Reset the attached device */
-               ufshcd_vops_device_reset(hba);
+               ufshcd_device_reset(hba);
  
                err = ufshcd_host_reset_and_restore(hba);
        } while (err && --retries);
@@@ -8045,7 -8029,7 +8064,7 @@@ static int ufshcd_disable_vreg(struct d
  {
        int ret = 0;
  
-       if (!vreg || !vreg->enabled)
+       if (!vreg || !vreg->enabled || vreg->always_on)
                goto out;
  
        ret = regulator_disable(vreg->reg);
@@@ -8414,13 -8398,7 +8433,7 @@@ static int ufshcd_set_dev_pwr_mode(stru
         * handling context.
         */
        hba->host->eh_noresume = 1;
-       if (hba->wlun_dev_clr_ua) {
-               ret = ufshcd_send_request_sense(hba, sdp);
-               if (ret)
-                       goto out;
-               /* Unit attention condition is cleared now */
-               hba->wlun_dev_clr_ua = false;
-       }
+       ufshcd_clear_ua_wluns(hba);
  
        cmd[4] = pwr_mode << 4;
  
  
        if (!ret)
                hba->curr_dev_pwr_mode = pwr_mode;
- out:
        scsi_device_put(sdp);
        hba->host->eh_noresume = 0;
        return ret;
@@@ -8747,7 -8725,7 +8760,7 @@@ set_link_active
         * further below.
         */
        if (ufshcd_is_ufs_dev_deepsleep(hba)) {
-               ufshcd_vops_device_reset(hba);
+               ufshcd_device_reset(hba);
                WARN_ON(!ufshcd_is_link_off(hba));
        }
        if (ufshcd_is_link_hibern8(hba) && !ufshcd_uic_hibern8_exit(hba))
  set_dev_active:
        /* Can also get here needing to exit DeepSleep */
        if (ufshcd_is_ufs_dev_deepsleep(hba)) {
-               ufshcd_vops_device_reset(hba);
+               ufshcd_device_reset(hba);
                ufshcd_host_reset_and_restore(hba);
        }
        if (!ufshcd_set_dev_pwr_mode(hba, UFS_ACTIVE_PWR_MODE))
@@@ -9085,7 -9063,11 +9098,7 @@@ int ufshcd_shutdown(struct ufs_hba *hba
        if (ufshcd_is_ufs_dev_poweroff(hba) && ufshcd_is_link_off(hba))
                goto out;
  
 -      if (pm_runtime_suspended(hba->dev)) {
 -              ret = ufshcd_runtime_resume(hba);
 -              if (ret)
 -                      goto out;
 -      }
 +      pm_runtime_get_sync(hba->dev);
  
        ret = ufshcd_suspend(hba, UFS_SHUTDOWN_PM);
  out:
@@@ -9111,7 -9093,6 +9124,7 @@@ void ufshcd_remove(struct ufs_hba *hba
        blk_mq_free_tag_set(&hba->tmf_tag_set);
        blk_cleanup_queue(hba->cmd_queue);
        scsi_remove_host(hba->host);
 +      destroy_workqueue(hba->eh_wq);
        /* disable interrupts */
        ufshcd_disable_intr(hba, hba->intr_mask);
        ufshcd_hba_stop(hba);
@@@ -9353,7 -9334,7 +9366,7 @@@ int ufshcd_init(struct ufs_hba *hba, vo
        }
  
        /* Reset the attached device */
-       ufshcd_vops_device_reset(hba);
+       ufshcd_device_reset(hba);
  
        ufshcd_init_crypto(hba);
  
@@@ -9414,7 -9395,6 +9427,7 @@@ out_remove_scsi_host
  exit_gating:
        ufshcd_exit_clk_scaling(hba);
        ufshcd_exit_clk_gating(hba);
 +      destroy_workqueue(hba->eh_wq);
  out_disable:
        hba->is_irq_enabled = false;
        ufshcd_hba_exit(hba);
@@@ -87,7 -87,6 +87,7 @@@ enum ufs_event_type 
   * @argument1: UIC command argument 1
   * @argument2: UIC command argument 2
   * @argument3: UIC command argument 3
 + * @cmd_active: Indicate if UIC command is outstanding
   * @done: UIC command completion
   */
  struct uic_command {
@@@ -95,7 -94,6 +95,7 @@@
        u32 argument1;
        u32 argument2;
        u32 argument3;
 +      int cmd_active;
        struct completion done;
  };
  
@@@ -1218,16 -1216,12 +1218,12 @@@ static inline void ufshcd_vops_dbg_regi
                hba->vops->dbg_register_dump(hba);
  }
  
- static inline void ufshcd_vops_device_reset(struct ufs_hba *hba)
+ static inline int ufshcd_vops_device_reset(struct ufs_hba *hba)
  {
-       if (hba->vops && hba->vops->device_reset) {
-               int err = hba->vops->device_reset(hba);
-               if (!err)
-                       ufshcd_set_ufs_dev_active(hba);
-               if (err != -EOPNOTSUPP)
-                       ufshcd_update_evt_hist(hba, UFS_EVT_DEV_RESET, err);
-       }
+       if (hba->vops && hba->vops->device_reset)
+               return hba->vops->device_reset(hba);
+       return -EOPNOTSUPP;
  }
  
  static inline void ufshcd_vops_config_scaling_param(struct ufs_hba *hba,
diff --combined include/linux/blk-mq.h
@@@ -5,7 -5,6 +5,7 @@@
  #include <linux/blkdev.h>
  #include <linux/sbitmap.h>
  #include <linux/srcu.h>
 +#include <linux/lockdep.h>
  
  struct blk_mq_tags;
  struct blk_flush_queue;
@@@ -236,8 -235,6 +236,8 @@@ enum hctx_type 
   * @flags:       Zero or more BLK_MQ_F_* flags.
   * @driver_data:   Pointer to data owned by the block driver that created this
   *               tag set.
 + * @active_queues_shared_sbitmap:
 + *               number of active request queues per tag set.
   * @__bitmap_tags: A shared tags sbitmap, used over all hctx's
   * @__breserved_tags:
   *               A shared reserved tags sbitmap, used over all hctx's
@@@ -447,8 -444,8 +447,8 @@@ enum 
        BLK_MQ_REQ_NOWAIT       = (__force blk_mq_req_flags_t)(1 << 0),
        /* allocate from reserved pool */
        BLK_MQ_REQ_RESERVED     = (__force blk_mq_req_flags_t)(1 << 1),
-       /* set RQF_PREEMPT */
-       BLK_MQ_REQ_PREEMPT      = (__force blk_mq_req_flags_t)(1 << 3),
+       /* set RQF_PM */
+       BLK_MQ_REQ_PM           = (__force blk_mq_req_flags_t)(1 << 2),
  };
  
  struct request *blk_mq_alloc_request(struct request_queue *q, unsigned int op,
@@@ -594,20 -591,6 +594,20 @@@ static inline void blk_mq_cleanup_rq(st
                rq->q->mq_ops->cleanup_rq(rq);
  }
  
 +static inline void blk_rq_bio_prep(struct request *rq, struct bio *bio,
 +              unsigned int nr_segs)
 +{
 +      rq->nr_phys_segments = nr_segs;
 +      rq->__data_len = bio->bi_iter.bi_size;
 +      rq->bio = rq->biotail = bio;
 +      rq->ioprio = bio_prio(bio);
 +
 +      if (bio->bi_disk)
 +              rq->rq_disk = bio->bi_disk;
 +}
 +
  blk_qc_t blk_mq_submit_bio(struct bio *bio);
 +void blk_mq_hctx_set_fq_lock_class(struct blk_mq_hw_ctx *hctx,
 +              struct lock_class_key *key);
  
  #endif
diff --combined include/linux/blkdev.h
@@@ -79,9 -79,6 +79,6 @@@ typedef __u32 __bitwise req_flags_t
  #define RQF_MQ_INFLIGHT               ((__force req_flags_t)(1 << 6))
  /* don't call prep for this one */
  #define RQF_DONTPREP          ((__force req_flags_t)(1 << 7))
- /* set for "ide_preempt" requests and also for requests for which the SCSI
-    "quiesce" state must be ignored. */
- #define RQF_PREEMPT           ((__force req_flags_t)(1 << 8))
  /* vaguely specified driver internal error.  Ignored by the block layer */
  #define RQF_FAILED            ((__force req_flags_t)(1 << 10))
  /* don't warn about errors */
@@@ -191,7 -188,7 +188,7 @@@ struct request 
        };
  
        struct gendisk *rq_disk;
 -      struct hd_struct *part;
 +      struct block_device *part;
  #ifdef CONFIG_BLK_RQ_ALLOC_TIME
        /* Time that the first bio started allocating this request. */
        u64 alloc_time_ns;
@@@ -430,8 -427,7 +427,7 @@@ struct request_queue 
        unsigned long           queue_flags;
        /*
         * Number of contexts that have called blk_set_pm_only(). If this
-        * counter is above zero then only RQF_PM and RQF_PREEMPT requests are
-        * processed.
+        * counter is above zero then only RQF_PM requests are processed.
         */
        atomic_t                pm_only;
  
@@@ -696,6 -692,18 +692,18 @@@ static inline bool queue_is_mq(struct r
        return q->mq_ops;
  }
  
+ #ifdef CONFIG_PM
+ static inline enum rpm_status queue_rpm_status(struct request_queue *q)
+ {
+       return q->rpm_status;
+ }
+ #else
+ static inline enum rpm_status queue_rpm_status(struct request_queue *q)
+ {
+       return RPM_ACTIVE;
+ }
+ #endif
  static inline enum blk_zoned_model
  blk_queue_zoned_model(struct request_queue *q)
  {
@@@ -1073,15 -1081,12 +1081,15 @@@ static inline unsigned int blk_queue_ge
   * file system requests.
   */
  static inline unsigned int blk_max_size_offset(struct request_queue *q,
 -                                             sector_t offset)
 -{
 -      unsigned int chunk_sectors = q->limits.chunk_sectors;
 -
 -      if (!chunk_sectors)
 -              return q->limits.max_sectors;
 +                                             sector_t offset,
 +                                             unsigned int chunk_sectors)
 +{
 +      if (!chunk_sectors) {
 +              if (q->limits.chunk_sectors)
 +                      chunk_sectors = q->limits.chunk_sectors;
 +              else
 +                      return q->limits.max_sectors;
 +      }
  
        if (likely(is_power_of_2(chunk_sectors)))
                chunk_sectors -= offset & (chunk_sectors - 1);
@@@ -1104,7 -1109,7 +1112,7 @@@ static inline unsigned int blk_rq_get_m
            req_op(rq) == REQ_OP_SECURE_ERASE)
                return blk_queue_get_max_sectors(q, req_op(rq));
  
 -      return min(blk_max_size_offset(q, offset),
 +      return min(blk_max_size_offset(q, offset, 0),
                        blk_queue_get_max_sectors(q, req_op(rq)));
  }
  
@@@ -1491,7 -1496,7 +1499,7 @@@ static inline int bdev_alignment_offset
                return -1;
        if (bdev_is_partition(bdev))
                return queue_limit_alignment_offset(&q->limits,
 -                              bdev->bd_part->start_sect);
 +                              bdev->bd_start_sect);
        return q->limits.alignment_offset;
  }
  
@@@ -1532,7 -1537,7 +1540,7 @@@ static inline int bdev_discard_alignmen
  
        if (bdev_is_partition(bdev))
                return queue_limit_discard_alignment(&q->limits,
 -                              bdev->bd_part->start_sect);
 +                              bdev->bd_start_sect);
        return q->limits.discard_alignment;
  }
  
@@@ -1853,7 -1858,6 +1861,7 @@@ struct block_device_operations 
        void (*unlock_native_capacity) (struct gendisk *);
        int (*revalidate_disk) (struct gendisk *);
        int (*getgeo)(struct block_device *, struct hd_geometry *);
 +      int (*set_read_only)(struct block_device *bdev, bool ro);
        /* this callback is with swap_lock and sometimes page table lock held */
        void (*swap_slot_free_notify) (struct block_device *, unsigned long);
        int (*report_zones)(struct gendisk *, sector_t sector,
@@@ -1870,6 -1874,8 +1878,6 @@@ extern int blkdev_compat_ptr_ioctl(stru
  #define blkdev_compat_ptr_ioctl NULL
  #endif
  
 -extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int,
 -                               unsigned long);
  extern int bdev_read_page(struct block_device *, sector_t, struct page *);
  extern int bdev_write_page(struct block_device *, sector_t, struct page *,
                                                struct writeback_control *);
@@@ -1946,9 -1952,9 +1954,9 @@@ unsigned long disk_start_io_acct(struc
  void disk_end_io_acct(struct gendisk *disk, unsigned int op,
                unsigned long start_time);
  
 -unsigned long part_start_io_acct(struct gendisk *disk, struct hd_struct **part,
 -                               struct bio *bio);
 -void part_end_io_acct(struct hd_struct *part, struct bio *bio,
 +unsigned long part_start_io_acct(struct gendisk *disk,
 +              struct block_device **part, struct bio *bio);
 +void part_end_io_acct(struct block_device *part, struct bio *bio,
                      unsigned long start_time);
  
  /**
@@@ -1976,7 -1982,7 +1984,7 @@@ int bdev_read_only(struct block_device 
  int set_blocksize(struct block_device *bdev, int size);
  
  const char *bdevname(struct block_device *bdev, char *buffer);
 -struct block_device *lookup_bdev(const char *);
 +int lookup_bdev(const char *pathname, dev_t *dev);
  
  void blkdev_show(struct seq_file *seqf, off_t offset);
  
  struct block_device *blkdev_get_by_path(const char *path, fmode_t mode,
                void *holder);
  struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode, void *holder);
 -int bd_prepare_to_claim(struct block_device *bdev, struct block_device *whole,
 -              void *holder);
 -void bd_abort_claiming(struct block_device *bdev, struct block_device *whole,
 -              void *holder);
 +int bd_prepare_to_claim(struct block_device *bdev, void *holder);
 +void bd_abort_claiming(struct block_device *bdev, void *holder);
  void blkdev_put(struct block_device *bdev, fmode_t mode);
  
 +/* just for blk-cgroup, don't use elsewhere */
 +struct block_device *blkdev_get_no_open(dev_t dev);
 +void blkdev_put_no_open(struct block_device *bdev);
 +
 +struct block_device *bdev_alloc(struct gendisk *disk, u8 partno);
 +void bdev_add(struct block_device *bdev, dev_t dev);
  struct block_device *I_BDEV(struct inode *inode);
 -struct block_device *bdget_part(struct hd_struct *part);
  struct block_device *bdgrab(struct block_device *bdev);
  void bdput(struct block_device *);
  
@@@ -2026,7 -2029,7 +2034,7 @@@ static inline int sync_blockdev(struct 
  #endif
  int fsync_bdev(struct block_device *bdev);
  
 -struct super_block *freeze_bdev(struct block_device *bdev);
 -int thaw_bdev(struct block_device *bdev, struct super_block *sb);
 +int freeze_bdev(struct block_device *bdev);
 +int thaw_bdev(struct block_device *bdev);
  
  #endif /* _LINUX_BLKDEV_H */