Commit 6a398a3e authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-4.2/drivers' of git://git.kernel.dk/linux-block

Pull block driver updates from Jens Axboe:
 "This contains:

   - a few race fixes for null_blk, from Akinobu Mita.

   - a series of fixes for mtip32xx, from Asai Thambi and Selvan Mani at
     Micron.

   - NVMe:
        * Fix for missing error return on allocation failure, from Axel
          Lin.

        * Code consolidation and cleanups from Christoph.

        * Memory barrier addition, syncing queue count and queue
          pointers. From Jon Derrick.

        * Various fixes from Keith, an addition to support user
          issue reset from sysfs or ioctl, and automatic namespace
          rescan.

        * Fix from Matias, avoiding losing some request flags when
          marking the request failfast.

   - small cleanups and sparse fixups for ps3vram.  From Geert
     Uytterhoeven and Geoff Lavand.

   - s390/dasd dead code removal, from Jarod Wilson.

   - a set of fixes and optimizations for loop, from Ming Lei.

   - conversion to blkdev_reread_part() of loop, dasd, ndb.  From Ming
     Lei.

   - updates to cciss.  From Tomas Henzl"

* 'for-4.2/drivers' of git://git.kernel.dk/linux-block: (44 commits)
  mtip32xx: Fix accessing freed memory
  block: nvme-scsi: Catch kcalloc failure
  NVMe: Fix IO for extended metadata formats
  nvme: don't overwrite req->cmd_flags on sync cmd
  mtip32xx: increase wait time for hba reset
  mtip32xx: fix minor number
  mtip32xx: remove unnecessary sleep in mtip_ftl_rebuild_poll()
  mtip32xx: fix crash on surprise removal of the drive
  mtip32xx: Abort I/O during secure erase operation
  mtip32xx: fix incorrectly setting MTIP_DDF_SEC_LOCK_BIT
  mtip32xx: remove unused variable 'port->allocated'
  mtip32xx: fix rmmod issue
  MAINTAINERS: Update ps3vram block driver
  block/ps3vram: Remove obsolete reference to MTD
  block/ps3vram: Fix sparse warnings
  NVMe: Automatic namespace rescan
  NVMe: Memory barrier before queue_count is incremented
  NVMe: add sysfs and ioctl controller reset
  null_blk: restart request processing on completion handler
  null_blk: prevent timer handler running on a different CPU where started
  ...
parents bfffa1cc 98f57c51
...@@ -7982,6 +7982,7 @@ F: sound/ppc/snd_ps3* ...@@ -7982,6 +7982,7 @@ F: sound/ppc/snd_ps3*
PS3VRAM DRIVER PS3VRAM DRIVER
M: Jim Paris <jim@jtan.com> M: Jim Paris <jim@jtan.com>
M: Geoff Levand <geoff@infradead.org>
L: linuxppc-dev@lists.ozlabs.org L: linuxppc-dev@lists.ozlabs.org
S: Maintained S: Maintained
F: drivers/block/ps3vram.c F: drivers/block/ps3vram.c
......
...@@ -86,8 +86,6 @@ static DEFINE_MUTEX(loop_index_mutex); ...@@ -86,8 +86,6 @@ static DEFINE_MUTEX(loop_index_mutex);
static int max_part; static int max_part;
static int part_shift; static int part_shift;
static struct workqueue_struct *loop_wq;
static int transfer_xor(struct loop_device *lo, int cmd, static int transfer_xor(struct loop_device *lo, int cmd,
struct page *raw_page, unsigned raw_off, struct page *raw_page, unsigned raw_off,
struct page *loop_page, unsigned loop_off, struct page *loop_page, unsigned loop_off,
...@@ -476,6 +474,28 @@ static int loop_flush(struct loop_device *lo) ...@@ -476,6 +474,28 @@ static int loop_flush(struct loop_device *lo)
return loop_switch(lo, NULL); return loop_switch(lo, NULL);
} }
static void loop_reread_partitions(struct loop_device *lo,
struct block_device *bdev)
{
int rc;
/*
* bd_mutex has been held already in release path, so don't
* acquire it if this function is called in such case.
*
* If the reread partition isn't from release path, lo_refcnt
* must be at least one and it can only become zero when the
* current holder is released.
*/
if (!atomic_read(&lo->lo_refcnt))
rc = __blkdev_reread_part(bdev);
else
rc = blkdev_reread_part(bdev);
if (rc)
pr_warn("%s: partition scan of loop%d (%s) failed (rc=%d)\n",
__func__, lo->lo_number, lo->lo_file_name, rc);
}
/* /*
* loop_change_fd switched the backing store of a loopback device to * loop_change_fd switched the backing store of a loopback device to
* a new file. This is useful for operating system installers to free up * a new file. This is useful for operating system installers to free up
...@@ -524,7 +544,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, ...@@ -524,7 +544,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
fput(old_file); fput(old_file);
if (lo->lo_flags & LO_FLAGS_PARTSCAN) if (lo->lo_flags & LO_FLAGS_PARTSCAN)
ioctl_by_bdev(bdev, BLKRRPART, 0); loop_reread_partitions(lo, bdev);
return 0; return 0;
out_putf: out_putf:
...@@ -725,6 +745,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, ...@@ -725,6 +745,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
size = get_loop_size(lo, file); size = get_loop_size(lo, file);
if ((loff_t)(sector_t)size != size) if ((loff_t)(sector_t)size != size)
goto out_putf; goto out_putf;
error = -ENOMEM;
lo->wq = alloc_workqueue("kloopd%d",
WQ_MEM_RECLAIM | WQ_HIGHPRI | WQ_UNBOUND, 16,
lo->lo_number);
if (!lo->wq)
goto out_putf;
error = 0; error = 0;
...@@ -755,7 +781,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, ...@@ -755,7 +781,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
if (part_shift) if (part_shift)
lo->lo_flags |= LO_FLAGS_PARTSCAN; lo->lo_flags |= LO_FLAGS_PARTSCAN;
if (lo->lo_flags & LO_FLAGS_PARTSCAN) if (lo->lo_flags & LO_FLAGS_PARTSCAN)
ioctl_by_bdev(bdev, BLKRRPART, 0); loop_reread_partitions(lo, bdev);
/* Grab the block_device to prevent its destruction after we /* Grab the block_device to prevent its destruction after we
* put /dev/loopXX inode. Later in loop_clr_fd() we bdput(bdev). * put /dev/loopXX inode. Later in loop_clr_fd() we bdput(bdev).
...@@ -827,7 +853,7 @@ static int loop_clr_fd(struct loop_device *lo) ...@@ -827,7 +853,7 @@ static int loop_clr_fd(struct loop_device *lo)
* <dev>/do something like mkfs/losetup -d <dev> causing the losetup -d * <dev>/do something like mkfs/losetup -d <dev> causing the losetup -d
* command to fail with EBUSY. * command to fail with EBUSY.
*/ */
if (lo->lo_refcnt > 1) { if (atomic_read(&lo->lo_refcnt) > 1) {
lo->lo_flags |= LO_FLAGS_AUTOCLEAR; lo->lo_flags |= LO_FLAGS_AUTOCLEAR;
mutex_unlock(&lo->lo_ctl_mutex); mutex_unlock(&lo->lo_ctl_mutex);
return 0; return 0;
...@@ -836,6 +862,9 @@ static int loop_clr_fd(struct loop_device *lo) ...@@ -836,6 +862,9 @@ static int loop_clr_fd(struct loop_device *lo)
if (filp == NULL) if (filp == NULL)
return -EINVAL; return -EINVAL;
/* freeze request queue during the transition */
blk_mq_freeze_queue(lo->lo_queue);
spin_lock_irq(&lo->lo_lock); spin_lock_irq(&lo->lo_lock);
lo->lo_state = Lo_rundown; lo->lo_state = Lo_rundown;
lo->lo_backing_file = NULL; lo->lo_backing_file = NULL;
...@@ -867,11 +896,15 @@ static int loop_clr_fd(struct loop_device *lo) ...@@ -867,11 +896,15 @@ static int loop_clr_fd(struct loop_device *lo)
lo->lo_state = Lo_unbound; lo->lo_state = Lo_unbound;
/* This is safe: open() is still holding a reference. */ /* This is safe: open() is still holding a reference. */
module_put(THIS_MODULE); module_put(THIS_MODULE);
blk_mq_unfreeze_queue(lo->lo_queue);
if (lo->lo_flags & LO_FLAGS_PARTSCAN && bdev) if (lo->lo_flags & LO_FLAGS_PARTSCAN && bdev)
ioctl_by_bdev(bdev, BLKRRPART, 0); loop_reread_partitions(lo, bdev);
lo->lo_flags = 0; lo->lo_flags = 0;
if (!part_shift) if (!part_shift)
lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN; lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN;
destroy_workqueue(lo->wq);
lo->wq = NULL;
mutex_unlock(&lo->lo_ctl_mutex); mutex_unlock(&lo->lo_ctl_mutex);
/* /*
* Need not hold lo_ctl_mutex to fput backing file. * Need not hold lo_ctl_mutex to fput backing file.
...@@ -943,7 +976,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) ...@@ -943,7 +976,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
!(lo->lo_flags & LO_FLAGS_PARTSCAN)) { !(lo->lo_flags & LO_FLAGS_PARTSCAN)) {
lo->lo_flags |= LO_FLAGS_PARTSCAN; lo->lo_flags |= LO_FLAGS_PARTSCAN;
lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN; lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
ioctl_by_bdev(lo->lo_device, BLKRRPART, 0); loop_reread_partitions(lo, lo->lo_device);
} }
lo->lo_encrypt_key_size = info->lo_encrypt_key_size; lo->lo_encrypt_key_size = info->lo_encrypt_key_size;
...@@ -1324,9 +1357,7 @@ static int lo_open(struct block_device *bdev, fmode_t mode) ...@@ -1324,9 +1357,7 @@ static int lo_open(struct block_device *bdev, fmode_t mode)
goto out; goto out;
} }
mutex_lock(&lo->lo_ctl_mutex); atomic_inc(&lo->lo_refcnt);
lo->lo_refcnt++;
mutex_unlock(&lo->lo_ctl_mutex);
out: out:
mutex_unlock(&loop_index_mutex); mutex_unlock(&loop_index_mutex);
return err; return err;
...@@ -1337,11 +1368,10 @@ static void lo_release(struct gendisk *disk, fmode_t mode) ...@@ -1337,11 +1368,10 @@ static void lo_release(struct gendisk *disk, fmode_t mode)
struct loop_device *lo = disk->private_data; struct loop_device *lo = disk->private_data;
int err; int err;
mutex_lock(&lo->lo_ctl_mutex); if (atomic_dec_return(&lo->lo_refcnt))
return;
if (--lo->lo_refcnt)
goto out;
mutex_lock(&lo->lo_ctl_mutex);
if (lo->lo_flags & LO_FLAGS_AUTOCLEAR) { if (lo->lo_flags & LO_FLAGS_AUTOCLEAR) {
/* /*
* In autoclear mode, stop the loop thread * In autoclear mode, stop the loop thread
...@@ -1358,7 +1388,6 @@ static void lo_release(struct gendisk *disk, fmode_t mode) ...@@ -1358,7 +1388,6 @@ static void lo_release(struct gendisk *disk, fmode_t mode)
loop_flush(lo); loop_flush(lo);
} }
out:
mutex_unlock(&lo->lo_ctl_mutex); mutex_unlock(&lo->lo_ctl_mutex);
} }
...@@ -1425,9 +1454,13 @@ static int loop_queue_rq(struct blk_mq_hw_ctx *hctx, ...@@ -1425,9 +1454,13 @@ static int loop_queue_rq(struct blk_mq_hw_ctx *hctx,
const struct blk_mq_queue_data *bd) const struct blk_mq_queue_data *bd)
{ {
struct loop_cmd *cmd = blk_mq_rq_to_pdu(bd->rq); struct loop_cmd *cmd = blk_mq_rq_to_pdu(bd->rq);
struct loop_device *lo = cmd->rq->q->queuedata;
blk_mq_start_request(bd->rq); blk_mq_start_request(bd->rq);
if (lo->lo_state != Lo_bound)
return -EIO;
if (cmd->rq->cmd_flags & REQ_WRITE) { if (cmd->rq->cmd_flags & REQ_WRITE) {
struct loop_device *lo = cmd->rq->q->queuedata; struct loop_device *lo = cmd->rq->q->queuedata;
bool need_sched = true; bool need_sched = true;
...@@ -1441,9 +1474,9 @@ static int loop_queue_rq(struct blk_mq_hw_ctx *hctx, ...@@ -1441,9 +1474,9 @@ static int loop_queue_rq(struct blk_mq_hw_ctx *hctx,
spin_unlock_irq(&lo->lo_lock); spin_unlock_irq(&lo->lo_lock);
if (need_sched) if (need_sched)
queue_work(loop_wq, &lo->write_work); queue_work(lo->wq, &lo->write_work);
} else { } else {
queue_work(loop_wq, &cmd->read_work); queue_work(lo->wq, &cmd->read_work);
} }
return BLK_MQ_RQ_QUEUE_OK; return BLK_MQ_RQ_QUEUE_OK;
...@@ -1455,9 +1488,6 @@ static void loop_handle_cmd(struct loop_cmd *cmd) ...@@ -1455,9 +1488,6 @@ static void loop_handle_cmd(struct loop_cmd *cmd)
struct loop_device *lo = cmd->rq->q->queuedata; struct loop_device *lo = cmd->rq->q->queuedata;
int ret = -EIO; int ret = -EIO;
if (lo->lo_state != Lo_bound)
goto failed;
if (write && (lo->lo_flags & LO_FLAGS_READ_ONLY)) if (write && (lo->lo_flags & LO_FLAGS_READ_ONLY))
goto failed; goto failed;
...@@ -1594,6 +1624,7 @@ static int loop_add(struct loop_device **l, int i) ...@@ -1594,6 +1624,7 @@ static int loop_add(struct loop_device **l, int i)
disk->flags |= GENHD_FL_NO_PART_SCAN; disk->flags |= GENHD_FL_NO_PART_SCAN;
disk->flags |= GENHD_FL_EXT_DEVT; disk->flags |= GENHD_FL_EXT_DEVT;
mutex_init(&lo->lo_ctl_mutex); mutex_init(&lo->lo_ctl_mutex);
atomic_set(&lo->lo_refcnt, 0);
lo->lo_number = i; lo->lo_number = i;
spin_lock_init(&lo->lo_lock); spin_lock_init(&lo->lo_lock);
disk->major = LOOP_MAJOR; disk->major = LOOP_MAJOR;
...@@ -1711,7 +1742,7 @@ static long loop_control_ioctl(struct file *file, unsigned int cmd, ...@@ -1711,7 +1742,7 @@ static long loop_control_ioctl(struct file *file, unsigned int cmd,
mutex_unlock(&lo->lo_ctl_mutex); mutex_unlock(&lo->lo_ctl_mutex);
break; break;
} }
if (lo->lo_refcnt > 0) { if (atomic_read(&lo->lo_refcnt) > 0) {
ret = -EBUSY; ret = -EBUSY;
mutex_unlock(&lo->lo_ctl_mutex); mutex_unlock(&lo->lo_ctl_mutex);
break; break;
...@@ -1806,13 +1837,6 @@ static int __init loop_init(void) ...@@ -1806,13 +1837,6 @@ static int __init loop_init(void)
goto misc_out; goto misc_out;
} }
loop_wq = alloc_workqueue("kloopd",
WQ_MEM_RECLAIM | WQ_HIGHPRI | WQ_UNBOUND, 0);
if (!loop_wq) {
err = -ENOMEM;
goto misc_out;
}
blk_register_region(MKDEV(LOOP_MAJOR, 0), range, blk_register_region(MKDEV(LOOP_MAJOR, 0), range,
THIS_MODULE, loop_probe, NULL, NULL); THIS_MODULE, loop_probe, NULL, NULL);
...@@ -1850,8 +1874,6 @@ static void __exit loop_exit(void) ...@@ -1850,8 +1874,6 @@ static void __exit loop_exit(void)
blk_unregister_region(MKDEV(LOOP_MAJOR, 0), range); blk_unregister_region(MKDEV(LOOP_MAJOR, 0), range);
unregister_blkdev(LOOP_MAJOR, "loop"); unregister_blkdev(LOOP_MAJOR, "loop");
destroy_workqueue(loop_wq);
misc_deregister(&loop_misc); misc_deregister(&loop_misc);
} }
......
...@@ -28,7 +28,7 @@ struct loop_func_table; ...@@ -28,7 +28,7 @@ struct loop_func_table;
struct loop_device { struct loop_device {
int lo_number; int lo_number;
int lo_refcnt; atomic_t lo_refcnt;
loff_t lo_offset; loff_t lo_offset;
loff_t lo_sizelimit; loff_t lo_sizelimit;
int lo_flags; int lo_flags;
...@@ -54,6 +54,7 @@ struct loop_device { ...@@ -54,6 +54,7 @@ struct loop_device {
gfp_t old_gfp_mask; gfp_t old_gfp_mask;
spinlock_t lo_lock; spinlock_t lo_lock;
struct workqueue_struct *wq;
struct list_head write_cmd_head; struct list_head write_cmd_head;
struct work_struct write_work; struct work_struct write_work;
bool write_started; bool write_started;
......
This diff is collapsed.
...@@ -142,7 +142,6 @@ enum { ...@@ -142,7 +142,6 @@ enum {
MTIP_PF_SVC_THD_ACTIVE_BIT = 4, MTIP_PF_SVC_THD_ACTIVE_BIT = 4,
MTIP_PF_ISSUE_CMDS_BIT = 5, MTIP_PF_ISSUE_CMDS_BIT = 5,
MTIP_PF_REBUILD_BIT = 6, MTIP_PF_REBUILD_BIT = 6,
MTIP_PF_SR_CLEANUP_BIT = 7,
MTIP_PF_SVC_THD_STOP_BIT = 8, MTIP_PF_SVC_THD_STOP_BIT = 8,
/* below are bit numbers in 'dd_flag' defined in driver_data */ /* below are bit numbers in 'dd_flag' defined in driver_data */
...@@ -150,7 +149,6 @@ enum { ...@@ -150,7 +149,6 @@ enum {
MTIP_DDF_REMOVE_PENDING_BIT = 1, MTIP_DDF_REMOVE_PENDING_BIT = 1,
MTIP_DDF_OVER_TEMP_BIT = 2, MTIP_DDF_OVER_TEMP_BIT = 2,
MTIP_DDF_WRITE_PROTECT_BIT = 3, MTIP_DDF_WRITE_PROTECT_BIT = 3,
MTIP_DDF_REMOVE_DONE_BIT = 4,
MTIP_DDF_CLEANUP_BIT = 5, MTIP_DDF_CLEANUP_BIT = 5,
MTIP_DDF_RESUME_BIT = 6, MTIP_DDF_RESUME_BIT = 6,
MTIP_DDF_INIT_DONE_BIT = 7, MTIP_DDF_INIT_DONE_BIT = 7,
...@@ -412,19 +410,13 @@ struct mtip_port { ...@@ -412,19 +410,13 @@ struct mtip_port {
* by the DMA when the driver issues internal commands. * by the DMA when the driver issues internal commands.
*/ */
dma_addr_t sector_buffer_dma; dma_addr_t sector_buffer_dma;
/*
* Bit significant, used to determine if a command slot has
* been allocated. i.e. the slot is in use. Bits are cleared
* when the command slot and all associated data structures
* are no longer needed.
*/
u16 *log_buf; u16 *log_buf;
dma_addr_t log_buf_dma; dma_addr_t log_buf_dma;
u8 *smart_buf; u8 *smart_buf;
dma_addr_t smart_buf_dma; dma_addr_t smart_buf_dma;
unsigned long allocated[SLOTBITS_IN_LONGS];
/* /*
* used to queue commands when an internal command is in progress * used to queue commands when an internal command is in progress
* or error handling is active * or error handling is active
......
...@@ -711,7 +711,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, ...@@ -711,7 +711,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
bdev->bd_inode->i_size = 0; bdev->bd_inode->i_size = 0;
set_capacity(nbd->disk, 0); set_capacity(nbd->disk, 0);
if (max_part > 0) if (max_part > 0)
ioctl_by_bdev(bdev, BLKRRPART, 0); blkdev_reread_part(bdev);
if (nbd->disconnect) /* user requested, ignore socket errors */ if (nbd->disconnect) /* user requested, ignore socket errors */
return 0; return 0;
return nbd->harderror; return nbd->harderror;
......
...@@ -243,6 +243,17 @@ static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer) ...@@ -243,6 +243,17 @@ static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer)
cmd = container_of(entry, struct nullb_cmd, ll_list); cmd = container_of(entry, struct nullb_cmd, ll_list);
entry = entry->next; entry = entry->next;
end_cmd(cmd); end_cmd(cmd);
if (cmd->rq) {
struct request_queue *q = cmd->rq->q;
if (!q->mq_ops && blk_queue_stopped(q)) {
spin_lock(q->queue_lock);
if (blk_queue_stopped(q))
blk_start_queue(q);
spin_unlock(q->queue_lock);
}
}
} while (entry); } while (entry);
} }
...@@ -257,7 +268,7 @@ static void null_cmd_end_timer(struct nullb_cmd *cmd) ...@@ -257,7 +268,7 @@ static void null_cmd_end_timer(struct nullb_cmd *cmd)
if (llist_add(&cmd->ll_list, &cq->list)) { if (llist_add(&cmd->ll_list, &cq->list)) {
ktime_t kt = ktime_set(0, completion_nsec); ktime_t kt = ktime_set(0, completion_nsec);
hrtimer_start(&cq->timer, kt, HRTIMER_MODE_REL); hrtimer_start(&cq->timer, kt, HRTIMER_MODE_REL_PINNED);
} }
put_cpu(); put_cpu();
...@@ -334,6 +345,7 @@ static int null_rq_prep_fn(struct request_queue *q, struct request *req) ...@@ -334,6 +345,7 @@ static int null_rq_prep_fn(struct request_queue *q, struct request *req)
req->special = cmd; req->special = cmd;
return BLKPREP_OK; return BLKPREP_OK;
} }
blk_stop_queue(q);
return BLKPREP_DEFER; return BLKPREP_DEFER;
} }
......
This diff is collapsed.
This diff is collapsed.
/* /*
* ps3vram - Use extra PS3 video ram as MTD block device. * ps3vram - Use extra PS3 video ram as block device.
* *
* Copyright 2009 Sony Corporation * Copyright 2009 Sony Corporation
* *
...@@ -73,8 +73,8 @@ struct ps3vram_priv { ...@@ -73,8 +73,8 @@ struct ps3vram_priv {
u64 memory_handle; u64 memory_handle;
u64 context_handle; u64 context_handle;
u32 *ctrl; u32 __iomem *ctrl;
void *reports; void __iomem *reports;
u8 *xdr_buf; u8 *xdr_buf;
u32 *fifo_base; u32 *fifo_base;
...@@ -104,7 +104,7 @@ static char *size = "256M"; ...@@ -104,7 +104,7 @@ static char *size = "256M";
module_param(size, charp, 0); module_param(size, charp, 0);
MODULE_PARM_DESC(size, "memory size"); MODULE_PARM_DESC(size, "memory size");
static u32 *ps3vram_get_notifier(void *reports, int notifier) static u32 __iomem *ps3vram_get_notifier(void __iomem *reports, int notifier)
{ {
return reports + DMA_NOTIFIER_OFFSET_BASE + return reports + DMA_NOTIFIER_OFFSET_BASE +
DMA_NOTIFIER_SIZE * notifier; DMA_NOTIFIER_SIZE * notifier;
...@@ -113,22 +113,22 @@ static u32 *ps3vram_get_notifier(void *reports, int notifier) ...@@ -113,22 +113,22 @@ static u32 *ps3vram_get_notifier(void *reports, int notifier)
static void ps3vram_notifier_reset(struct ps3_system_bus_device *dev) static void ps3vram_notifier_reset(struct ps3_system_bus_device *dev)
{ {
struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); u32 __iomem *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
int i; int i;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
notify[i] = 0xffffffff; iowrite32be(0xffffffff, notify + i);
} }
static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev, static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev,
unsigned int timeout_ms) unsigned int timeout_ms)
{ {
struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); u32 __iomem *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
unsigned long timeout; unsigned long timeout;
for (timeout = 20; timeout; timeout--) { for (timeout = 20; timeout; timeout--) {
if (!notify[3]) if (!ioread32be(notify + 3))
return 0; return 0;
udelay(10); udelay(10);
} }
...@@ -136,7 +136,7 @@ static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev, ...@@ -136,7 +136,7 @@ static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev,
timeout = jiffies + msecs_to_jiffies(timeout_ms); timeout = jiffies + msecs_to_jiffies(timeout_ms);
do { do {
if (!notify[3]) if (!ioread32be(notify + 3))
return 0; return 0;
msleep(1); msleep(1);
} while (time_before(jiffies, timeout)); } while (time_before(jiffies, timeout));
...@@ -148,8 +148,8 @@ static void ps3vram_init_ring(struct ps3_system_bus_device *dev) ...@@ -148,8 +148,8 @@ static void ps3vram_init_ring(struct ps3_system_bus_device *dev)
{ {
struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; iowrite32be(FIFO_BASE + FIFO_OFFSET, priv->ctrl + CTRL_PUT);
priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET; iowrite32be(FIFO_BASE + FIFO_OFFSET, priv->ctrl + CTRL_GET);
} }
static int ps3vram_wait_ring(struct ps3_system_bus_device *dev, static int ps3vram_wait_ring(struct ps3_system_bus_device *dev,
...@@ -159,14 +159,14 @@ static int ps3vram_wait_ring(struct ps3_system_bus_device *dev, ...@@ -159,14 +159,14 @@ static int ps3vram_wait_ring(struct ps3_system_bus_device *dev,
unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
do { do {
if (priv->ctrl[CTRL_PUT] == priv->ctrl[CTRL_GET]) if (ioread32be(priv->ctrl + CTRL_PUT) == ioread32be(priv->ctrl + CTRL_GET))
return 0; return 0;
msleep(1); msleep(1);
} while (time_before(jiffies, timeout)); } while (time_before(jiffies, timeout));
dev_warn(&dev->core, "FIFO timeout (%08x/%08x/%08x)\n", dev_warn(&dev->core, "FIFO timeout (%08x/%08x/%08x)\n",
priv->ctrl[CTRL_PUT], priv->ctrl[CTRL_GET], ioread32be(priv->ctrl + CTRL_PUT), ioread32be(priv->ctrl + CTRL_GET),
priv->ctrl[CTRL_TOP]); ioread32be(priv->ctrl + CTRL_TOP));
return -ETIMEDOUT; return -ETIMEDOUT;
} }
...@@ -189,7 +189,7 @@ static void ps3vram_rewind_ring(struct ps3_system_bus_device *dev) ...@@ -189,7 +189,7 @@ static void ps3vram_rewind_ring(struct ps3_system_bus_device *dev)
ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET)); ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET));
priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; iowrite32be(FIFO_BASE + FIFO_OFFSET, priv->ctrl + CTRL_PUT);
/* asking the HV for a blit will kick the FIFO */ /* asking the HV for a blit will kick the FIFO */
status = lv1_gpu_fb_blit(priv->context_handle, 0, 0, 0, 0); status = lv1_gpu_fb_blit(priv->context_handle, 0, 0, 0, 0);
...@@ -207,8 +207,8 @@ static void ps3vram_fire_ring(struct ps3_system_bus_device *dev) ...@@ -207,8 +207,8 @@ static void ps3vram_fire_ring(struct ps3_system_bus_device *dev)
mutex_lock(&ps3_gpu_mutex); mutex_lock(&ps3_gpu_mutex);
priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET + iowrite32be(FIFO_BASE + FIFO_OFFSET + (priv->fifo_ptr - priv->fifo_base)
(priv->fifo_ptr - priv->fifo_base) * sizeof(u32); * sizeof(u32), priv->ctrl + CTRL_PUT);
/* asking the HV for a blit will kick the FIFO */ /* asking the HV for a blit will kick the FIFO */
status = lv1_gpu_fb_blit(priv->context_handle, 0, 0, 0, 0); status = lv1_gpu_fb_blit(priv->context_handle, 0, 0, 0, 0);
......
...@@ -99,9 +99,8 @@ void dasd_gendisk_free(struct dasd_block *block) ...@@ -99,9 +99,8 @@ void dasd_gendisk_free(struct dasd_block *block)
int dasd_scan_partitions(struct dasd_block *block) int dasd_scan_partitions(struct dasd_block *block)
{ {
struct block_device *bdev; struct block_device *bdev;
int retry, rc; int rc;
retry = 5;
bdev = bdget_disk(block->gdp, 0); bdev = bdget_disk(block->gdp, 0);
if (!bdev) { if (!bdev) {
DBF_DEV_EVENT(DBF_ERR, block->base, "%s", DBF_DEV_EVENT(DBF_ERR, block->base, "%s",
...@@ -116,19 +115,11 @@ int dasd_scan_partitions(struct dasd_block *block) ...@@ -116,19 +115,11 @@ int dasd_scan_partitions(struct dasd_block *block)
rc); rc);
return -ENODEV; return -ENODEV;
} }
/*
* See fs/partition/check.c:register_disk,rescan_partitions rc = blkdev_reread_part(bdev);
* Can't call rescan_partitions directly. Use ioctl. if (rc)
*/
rc = ioctl_by_bdev(bdev, BLKRRPART, 0);
while (rc == -EBUSY && retry > 0) {
schedule();
rc = ioctl_by_bdev(bdev, BLKRRPART, 0);
retry--;
DBF_DEV_EVENT(DBF_ERR, block->base, DBF_DEV_EVENT(DBF_ERR, block->base,
"scan partitions error, retry %d rc %d", "scan partitions error, rc %d", rc);
retry, rc);
}
/* /*
* Since the matching blkdev_put call to the blkdev_get in * Since the matching blkdev_put call to the blkdev_get in
......
...@@ -74,7 +74,7 @@ struct nvme_dev { ...@@ -74,7 +74,7 @@ struct nvme_dev {
struct blk_mq_tag_set tagset; struct blk_mq_tag_set tagset;
struct blk_mq_tag_set admin_tagset; struct blk_mq_tag_set admin_tagset;
u32 __iomem *dbs; u32 __iomem *dbs;
struct pci_dev *pci_dev; struct device *dev;
struct dma_pool *prp_page_pool; struct dma_pool *prp_page_pool;
struct dma_pool *prp_small_pool; struct dma_pool *prp_small_pool;
int instance; int instance;
...@@ -92,6 +92,7 @@ struct nvme_dev { ...@@ -92,6 +92,7 @@ struct nvme_dev {
work_func_t reset_workfn; work_func_t reset_workfn;
struct work_struct reset_work; struct work_struct reset_work;
struct work_struct probe_work; struct work_struct probe_work;
struct work_struct scan_work;
char name[12]; char name[12];
char serial[20]; char serial[20];
char model[40]; char model[40];
...@@ -146,25 +147,15 @@ static inline u64 nvme_block_nr(struct nvme_ns *ns, sector_t sector) ...@@ -146,25 +147,15 @@ static inline u64 nvme_block_nr(struct nvme_ns *ns, sector_t sector)
return (sector >> (ns->lba_shift - 9)); return (sector >> (ns->lba_shift - 9));
} }
/** int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
* nvme_free_iod - frees an nvme_iod void *buf, unsigned bufflen);
* @dev: The device that the I/O was submitted to int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
* @iod: The memory to free void *buffer, void __user *ubuffer, unsigned bufflen,
*/ u32 *result, unsigned timeout);
void nvme_free_iod(struct nvme_dev *dev, struct nvme_iod *iod); int nvme_identify_ctrl(struct nvme_dev *dev, struct nvme_id_ctrl **id);
int nvme_identify_ns(struct nvme_dev *dev, unsigned nsid,
int nvme_setup_prps(struct nvme_dev *, struct nvme_iod *, int, gfp_t); struct nvme_id_ns **id);
struct nvme_iod *nvme_map_user_pages(struct nvme_dev *dev, int write, int nvme_get_log_page(struct nvme_dev *dev, struct nvme_smart_log **log);
unsigned long addr, unsigned length);
void nvme_unmap_user_pages(struct nvme_dev *dev, int write,
struct nvme_iod *iod);
int nvme_submit_io_cmd(struct nvme_dev *, struct nvme_ns *,
struct nvme_command *, u32 *);
int nvme_submit_flush_data(struct nvme_queue *nvmeq, struct nvme_ns *ns);
int nvme_submit_admin_cmd(struct nvme_dev *, struct nvme_command *,
u32 *result);
int nvme_identify(struct nvme_dev *, unsigned nsid, unsigned cns,
dma_addr_t dma_addr);
int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid, int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
dma_addr_t dma_addr, u32 *result); dma_addr_t dma_addr, u32 *result);
int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11, int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11,
......
...@@ -179,6 +179,10 @@ enum { ...@@ -179,6 +179,10 @@ enum {
NVME_SMART_CRIT_VOLATILE_MEMORY = 1 << 4, NVME_SMART_CRIT_VOLATILE_MEMORY = 1 << 4,
}; };
enum {
NVME_AER_NOTICE_NS_CHANGED = 0x0002,
};
struct nvme_lba_range_type { struct nvme_lba_range_type {
__u8 type; __u8 type;
__u8 attributes; __u8 attributes;
...@@ -579,5 +583,6 @@ struct nvme_passthru_cmd { ...@@ -579,5 +583,6 @@ struct nvme_passthru_cmd {
#define NVME_IOCTL_ADMIN_CMD _IOWR('N', 0x41, struct nvme_admin_cmd) #define NVME_IOCTL_ADMIN_CMD _IOWR('N', 0x41, struct nvme_admin_cmd)
#define NVME_IOCTL_SUBMIT_IO _IOW('N', 0x42, struct nvme_user_io) #define NVME_IOCTL_SUBMIT_IO _IOW('N', 0x42, struct nvme_user_io)
#define NVME_IOCTL_IO_CMD _IOWR('N', 0x43, struct nvme_passthru_cmd) #define NVME_IOCTL_IO_CMD _IOWR('N', 0x43, struct nvme_passthru_cmd)
#define NVME_IOCTL_RESET _IO('N', 0x44)
#endif /* _UAPI_LINUX_NVME_H */ #endif /* _UAPI_LINUX_NVME_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment