diff options
author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-09-05 18:22:45 +0400 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-09-05 18:22:45 +0400 |
commit | 593d0a3e9f813db910dc50574532914db21d09ff (patch) | |
tree | 12d8413ee57b4383ca8c906996ffe02be6d377a5 /drivers/s390/block/dasd.c | |
parent | 50e900417b8096939d12a46848f965e27a905e36 (diff) | |
parent | 4cb38750d49010ae72e718d46605ac9ba5a851b4 (diff) | |
download | linux-593d0a3e9f813db910dc50574532914db21d09ff.tar.xz |
Merge commit '4cb38750d49010ae72e718d46605ac9ba5a851b4' into stable/for-linus-3.6
* commit '4cb38750d49010ae72e718d46605ac9ba5a851b4': (6849 commits)
bcma: fix invalid PMU chip control masks
[libata] pata_cmd64x: whitespace cleanup
libata-acpi: fix up for acpi_pm_device_sleep_state API
sata_dwc_460ex: device tree may specify dma_channel
ahci, trivial: fixed coding style issues related to braces
ahci_platform: add hibernation callbacks
libata-eh.c: local functions should not be exposed globally
libata-transport.c: local functions should not be exposed globally
sata_dwc_460ex: support hardreset
ata: use module_pci_driver
drivers/ata/pata_pcmcia.c: adjust suspicious bit operation
pata_imx: Convert to clk_prepare_enable/clk_disable_unprepare
ahci: Enable SB600 64bit DMA on MSI K9AGM2 (MS-7327) v2
[libata] Prevent interface errors with Seagate FreeAgent GoFlex
drivers/acpi/glue: revert accidental license-related 6b66d95895c bits
libata-acpi: add missing inlines in libata.h
i2c-omap: Add support for I2C_M_STOP message flag
i2c: Fall back to emulated SMBus if the operation isn't supported natively
i2c: Add SCCB support
i2c-tiny-usb: Add support for the Robofuzz OSIF USB/I2C converter
...
Diffstat (limited to 'drivers/s390/block/dasd.c')
-rw-r--r-- | drivers/s390/block/dasd.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index f3509120a507..15370a2c5ff0 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -1,5 +1,4 @@ /* - * File...........: linux/drivers/s390/block/dasd.c * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> * Horst Hummel <Horst.Hummel@de.ibm.com> * Carsten Otte <Cotte@de.ibm.com> @@ -52,7 +51,7 @@ void dasd_int_handler(struct ccw_device *, unsigned long, struct irb *); MODULE_AUTHOR("Holger Smolinski <Holger.Smolinski@de.ibm.com>"); MODULE_DESCRIPTION("Linux on S/390 DASD device driver," - " Copyright 2000 IBM Corporation"); + " Copyright IBM Corp. 2000"); MODULE_SUPPORTED_DEVICE("dasd"); MODULE_LICENSE("GPL"); @@ -82,6 +81,7 @@ static void dasd_profile_exit(struct dasd_profile *); static wait_queue_head_t dasd_init_waitq; static wait_queue_head_t dasd_flush_wq; static wait_queue_head_t generic_waitq; +static wait_queue_head_t shutdown_waitq; /* * Allocate memory for a new device structure. @@ -1994,6 +1994,8 @@ static void dasd_device_tasklet(struct dasd_device *device) /* Now check if the head of the ccw queue needs to be started. */ __dasd_device_start_head(device); spin_unlock_irq(get_ccwdev_lock(device->cdev)); + if (waitqueue_active(&shutdown_waitq)) + wake_up(&shutdown_waitq); dasd_put_device(device); } @@ -2632,6 +2634,8 @@ static void dasd_block_tasklet(struct dasd_block *block) __dasd_block_start_head(block); spin_unlock(&block->queue_lock); spin_unlock_irq(&block->request_queue_lock); + if (waitqueue_active(&shutdown_waitq)) + wake_up(&shutdown_waitq); dasd_put_device(block->base); } @@ -3474,6 +3478,32 @@ char *dasd_get_sense(struct irb *irb) } EXPORT_SYMBOL_GPL(dasd_get_sense); +static inline int _wait_for_empty_queues(struct dasd_device *device) +{ + if (device->block) + return list_empty(&device->ccw_queue) && + list_empty(&device->block->ccw_queue); + else + return list_empty(&device->ccw_queue); +} + +void dasd_generic_shutdown(struct ccw_device *cdev) +{ + struct dasd_device *device; + + device = dasd_device_from_cdev(cdev); + if (IS_ERR(device)) + return; + + if (device->block) + dasd_schedule_block_bh(device->block); + + dasd_schedule_device_bh(device); + + wait_event(shutdown_waitq, _wait_for_empty_queues(device)); +} +EXPORT_SYMBOL_GPL(dasd_generic_shutdown); + static int __init dasd_init(void) { int rc; @@ -3481,6 +3511,7 @@ static int __init dasd_init(void) init_waitqueue_head(&dasd_init_waitq); init_waitqueue_head(&dasd_flush_wq); init_waitqueue_head(&generic_waitq); + init_waitqueue_head(&shutdown_waitq); /* register 'common' DASD debug area, used for all DBF_XXX calls */ dasd_debug_area = debug_register("dasd", 1, 1, 8 * sizeof(long)); |