aboutsummaryrefslogtreecommitdiff
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/Makefile4
-rw-r--r--drivers/s390/block/dasd.c1693
-rw-r--r--drivers/s390/block/dasd_3370_erp.c84
-rw-r--r--drivers/s390/block/dasd_3990_erp.c360
-rw-r--r--drivers/s390/block/dasd_9336_erp.c41
-rw-r--r--drivers/s390/block/dasd_9343_erp.c21
-rw-r--r--drivers/s390/block/dasd_alias.c903
-rw-r--r--drivers/s390/block/dasd_devmap.c94
-rw-r--r--drivers/s390/block/dasd_diag.c107
-rw-r--r--drivers/s390/block/dasd_eckd.c789
-rw-r--r--drivers/s390/block/dasd_eckd.h125
-rw-r--r--drivers/s390/block/dasd_eer.c11
-rw-r--r--drivers/s390/block/dasd_erp.c25
-rw-r--r--drivers/s390/block/dasd_fba.c119
-rw-r--r--drivers/s390/block/dasd_genhd.c76
-rw-r--r--drivers/s390/block/dasd_int.h209
-rw-r--r--drivers/s390/block/dasd_ioctl.c172
-rw-r--r--drivers/s390/block/dasd_proc.c23
-rw-r--r--drivers/s390/block/dcssblk.c2
-rw-r--r--drivers/s390/char/Makefile2
-rw-r--r--drivers/s390/char/monwriter.c2
-rw-r--r--drivers/s390/char/raw3270.c4
-rw-r--r--drivers/s390/char/sclp.h4
-rw-r--r--drivers/s390/char/sclp_chp.c200
-rw-r--r--drivers/s390/char/sclp_cmd.c398
-rw-r--r--drivers/s390/char/sclp_config.c4
-rw-r--r--drivers/s390/char/sclp_cpi.c246
-rw-r--r--drivers/s390/char/sclp_cpi_sys.c400
-rw-r--r--drivers/s390/char/sclp_cpi_sys.h15
-rw-r--r--drivers/s390/char/sclp_info.c116
-rw-r--r--drivers/s390/char/sclp_rw.c2
-rw-r--r--drivers/s390/char/tape_3590.c2
-rw-r--r--drivers/s390/char/tape_block.c13
-rw-r--r--drivers/s390/char/tape_core.c2
-rw-r--r--drivers/s390/char/tape_proc.c2
-rw-r--r--drivers/s390/char/vmlogrdr.c2
-rw-r--r--drivers/s390/char/vmur.c2
-rw-r--r--drivers/s390/char/zcore.c2
-rw-r--r--drivers/s390/cio/airq.c171
-rw-r--r--drivers/s390/cio/airq.h10
-rw-r--r--drivers/s390/cio/blacklist.c2
-rw-r--r--drivers/s390/cio/ccwgroup.c25
-rw-r--r--drivers/s390/cio/chsc.c121
-rw-r--r--drivers/s390/cio/cio.c106
-rw-r--r--drivers/s390/cio/cio.h89
-rw-r--r--drivers/s390/cio/cio_debug.h22
-rw-r--r--drivers/s390/cio/css.c198
-rw-r--r--drivers/s390/cio/css.h78
-rw-r--r--drivers/s390/cio/device.c157
-rw-r--r--drivers/s390/cio/device.h5
-rw-r--r--drivers/s390/cio/device_fsm.c124
-rw-r--r--drivers/s390/cio/device_id.c9
-rw-r--r--drivers/s390/cio/device_ops.c2
-rw-r--r--drivers/s390/cio/device_pgid.c6
-rw-r--r--drivers/s390/cio/device_status.c13
-rw-r--r--drivers/s390/cio/io_sch.h163
-rw-r--r--drivers/s390/cio/ioasm.h66
-rw-r--r--drivers/s390/cio/qdio.c38
-rw-r--r--drivers/s390/cio/qdio.h2
-rw-r--r--drivers/s390/net/claw.c2
-rw-r--r--drivers/s390/net/lcs.c2
-rw-r--r--drivers/s390/net/netiucv.c19
-rw-r--r--drivers/s390/net/qeth_main.c6
-rw-r--r--drivers/s390/net/qeth_proc.c4
-rw-r--r--drivers/s390/net/smsgiucv.c2
-rw-r--r--drivers/s390/scsi/zfcp_aux.c2
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c17
-rw-r--r--drivers/s390/scsi/zfcp_dbf.c6
-rw-r--r--drivers/s390/scsi/zfcp_def.h22
-rw-r--r--drivers/s390/scsi/zfcp_erp.c16
-rw-r--r--drivers/s390/scsi/zfcp_ext.h3
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c84
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c2
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c24
-rw-r--r--drivers/s390/scsi/zfcp_sysfs_driver.c27
75 files changed, 4950 insertions, 2971 deletions
diff --git a/drivers/s390/block/Makefile b/drivers/s390/block/Makefile
index be9f22d52fd..0a89e080b38 100644
--- a/drivers/s390/block/Makefile
+++ b/drivers/s390/block/Makefile
@@ -2,8 +2,8 @@
# S/390 block devices
#
-dasd_eckd_mod-objs := dasd_eckd.o dasd_3990_erp.o dasd_9343_erp.o
-dasd_fba_mod-objs := dasd_fba.o dasd_3370_erp.o dasd_9336_erp.o
+dasd_eckd_mod-objs := dasd_eckd.o dasd_3990_erp.o dasd_alias.o
+dasd_fba_mod-objs := dasd_fba.o
dasd_diag_mod-objs := dasd_diag.o
dasd_mod-objs := dasd.o dasd_ioctl.o dasd_proc.o dasd_devmap.o \
dasd_genhd.o dasd_erp.o
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index e6bfce690ca..d640427c74c 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -48,13 +48,15 @@ MODULE_LICENSE("GPL");
/*
* SECTION: prototypes for static functions of dasd.c
*/
-static int dasd_alloc_queue(struct dasd_device * device);
-static void dasd_setup_queue(struct dasd_device * device);
-static void dasd_free_queue(struct dasd_device * device);
-static void dasd_flush_request_queue(struct dasd_device *);
-static int dasd_flush_ccw_queue(struct dasd_device *, int);
-static void dasd_tasklet(struct dasd_device *);
+static int dasd_alloc_queue(struct dasd_block *);
+static void dasd_setup_queue(struct dasd_block *);
+static void dasd_free_queue(struct dasd_block *);
+static void dasd_flush_request_queue(struct dasd_block *);
+static int dasd_flush_block_queue(struct dasd_block *);
+static void dasd_device_tasklet(struct dasd_device *);
+static void dasd_block_tasklet(struct dasd_block *);
static void do_kick_device(struct work_struct *);
+static void dasd_return_cqr_cb(struct dasd_ccw_req *, void *);
/*
* SECTION: Operations on the device structure.
@@ -65,26 +67,23 @@ static wait_queue_head_t dasd_flush_wq;
/*
* Allocate memory for a new device structure.
*/
-struct dasd_device *
-dasd_alloc_device(void)
+struct dasd_device *dasd_alloc_device(void)
{
struct dasd_device *device;
- device = kzalloc(sizeof (struct dasd_device), GFP_ATOMIC);
- if (device == NULL)
+ device = kzalloc(sizeof(struct dasd_device), GFP_ATOMIC);
+ if (!device)
return ERR_PTR(-ENOMEM);
- /* open_count = 0 means device online but not in use */
- atomic_set(&device->open_count, -1);
/* Get two pages for normal block device operations. */
device->ccw_mem = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, 1);
- if (device->ccw_mem == NULL) {
+ if (!device->ccw_mem) {
kfree(device);
return ERR_PTR(-ENOMEM);
}
/* Get one page for error recovery. */
device->erp_mem = (void *) get_zeroed_page(GFP_ATOMIC | GFP_DMA);
- if (device->erp_mem == NULL) {
+ if (!device->erp_mem) {
free_pages((unsigned long) device->ccw_mem, 1);
kfree(device);
return ERR_PTR(-ENOMEM);
@@ -93,10 +92,9 @@ dasd_alloc_device(void)
dasd_init_chunklist(&device->ccw_chunks, device->ccw_mem, PAGE_SIZE*2);
dasd_init_chunklist(&device->erp_chunks, device->erp_mem, PAGE_SIZE);
spin_lock_init(&device->mem_lock);
- spin_lock_init(&device->request_queue_lock);
- atomic_set (&device->tasklet_scheduled, 0);
+ atomic_set(&device->tasklet_scheduled, 0);
tasklet_init(&device->tasklet,
- (void (*)(unsigned long)) dasd_tasklet,
+ (void (*)(unsigned long)) dasd_device_tasklet,
(unsigned long) device);
INIT_LIST_HEAD(&device->ccw_queue);
init_timer(&device->timer);
@@ -110,8 +108,7 @@ dasd_alloc_device(void)
/*
* Free memory of a device structure.
*/
-void
-dasd_free_device(struct dasd_device *device)
+void dasd_free_device(struct dasd_device *device)
{
kfree(device->private);
free_page((unsigned long) device->erp_mem);
@@ -120,10 +117,42 @@ dasd_free_device(struct dasd_device *device)
}
/*
+ * Allocate memory for a new device structure.
+ */
+struct dasd_block *dasd_alloc_block(void)
+{
+ struct dasd_block *block;
+
+ block = kzalloc(sizeof(*block), GFP_ATOMIC);
+ if (!block)
+ return ERR_PTR(-ENOMEM);
+ /* open_count = 0 means device online but not in use */
+ atomic_set(&block->open_count, -1);
+
+ spin_lock_init(&block->request_queue_lock);
+ atomic_set(&block->tasklet_scheduled, 0);
+ tasklet_init(&block->tasklet,
+ (void (*)(unsigned long)) dasd_block_tasklet,
+ (unsigned long) block);
+ INIT_LIST_HEAD(&block->ccw_queue);
+ spin_lock_init(&block->queue_lock);
+ init_timer(&block->timer);
+
+ return block;
+}
+
+/*
+ * Free memory of a device structure.
+ */
+void dasd_free_block(struct dasd_block *block)
+{
+ kfree(block);
+}
+
+/*
* Make a new device known to the system.
*/
-static int
-dasd_state_new_to_known(struct dasd_device *device)
+static int dasd_state_new_to_known(struct dasd_device *device)
{
int rc;
@@ -133,12 +162,13 @@ dasd_state_new_to_known(struct dasd_device *device)
*/
dasd_get_device(device);
- rc = dasd_alloc_queue(device);
- if (rc) {
- dasd_put_device(device);
- return rc;
+ if (device->block) {
+ rc = dasd_alloc_queue(device->block);
+ if (rc) {
+ dasd_put_device(device);
+ return rc;
+ }
}
-
device->state = DASD_STATE_KNOWN;
return 0;
}
@@ -146,21 +176,24 @@ dasd_state_new_to_known(struct dasd_device *device)
/*
* Let the system forget about a device.
*/
-static int
-dasd_state_known_to_new(struct dasd_device * device)
+static int dasd_state_known_to_new(struct dasd_device *device)
{
/* Disable extended error reporting for this device. */
dasd_eer_disable(device);
/* Forget the discipline information. */
- if (device->discipline)
+ if (device->discipline) {
+ if (device->discipline->uncheck_device)
+ device->discipline->uncheck_device(device);
module_put(device->discipline->owner);
+ }
device->discipline = NULL;
if (device->base_discipline)
module_put(device->base_discipline->owner);
device->base_discipline = NULL;
device->state = DASD_STATE_NEW;
- dasd_free_queue(device);
+ if (device->block)
+ dasd_free_queue(device->block);
/* Give up reference we took in dasd_state_new_to_known. */
dasd_put_device(device);
@@ -170,19 +203,19 @@ dasd_state_known_to_new(struct dasd_device * device)
/*
* Request the irq line for the device.
*/
-static int
-dasd_state_known_to_basic(struct dasd_device * device)
+static int dasd_state_known_to_basic(struct dasd_device *device)
{
int rc;
/* Allocate and register gendisk structure. */
- rc = dasd_gendisk_alloc(device);
- if (rc)
- return rc;
-
+ if (device->block) {
+ rc = dasd_gendisk_alloc(device->block);
+ if (rc)
+ return rc;
+ }
/* register 'device' debug area, used for all DBF_DEV_XXX calls */
- device->debug_area = debug_register(device->cdev->dev.bus_id, 1, 2,
- 8 * sizeof (long));
+ device->debug_area = debug_register(device->cdev->dev.bus_id, 1, 1,
+ 8 * sizeof(long));
debug_register_view(device->debug_area, &debug_sprintf_view);
debug_set_level(device->debug_area, DBF_WARNING);
DBF_DEV_EVENT(DBF_EMERG, device, "%s", "debug area created");
@@ -194,16 +227,17 @@ dasd_state_known_to_basic(struct dasd_device * device)
/*
* Release the irq line for the device. Terminate any running i/o.
*/
-static int
-dasd_state_basic_to_known(struct dasd_device * device)
+static int dasd_state_basic_to_known(struct dasd_device *device)
{
int rc;
-
- dasd_gendisk_free(device);
- rc = dasd_flush_ccw_queue(device, 1);
+ if (device->block) {
+ dasd_gendisk_free(device->block);
+ dasd_block_clear_timer(device->block);
+ }
+ rc = dasd_flush_device_queue(device);
if (rc)
return rc;
- dasd_clear_timer(device);
+ dasd_device_clear_timer(device);
DBF_DEV_EVENT(DBF_EMERG, device, "%p debug area deleted", device);
if (device->debug_area != NULL) {
@@ -228,26 +262,32 @@ dasd_state_basic_to_known(struct dasd_device * device)
* In case the analysis returns an error, the device setup is stopped
* (a fake disk was already added to allow formatting).
*/
-static int
-dasd_state_basic_to_ready(struct dasd_device * device)
+static int dasd_state_basic_to_ready(struct dasd_device *device)
{
int rc;
+ struct dasd_block *block;
rc = 0;
- if (device->discipline->do_analysis != NULL)
- rc = device->discipline->do_analysis(device);
- if (rc) {
- if (rc != -EAGAIN)
- device->state = DASD_STATE_UNFMT;
- return rc;
- }
+ block = device->block;
/* make disk known with correct capacity */
- dasd_setup_queue(device);
- set_capacity(device->gdp, device->blocks << device->s2b_shift);
- device->state = DASD_STATE_READY;
- rc = dasd_scan_partitions(device);
- if (rc)
- device->state = DASD_STATE_BASIC;
+ if (block) {
+ if (block->base->discipline->do_analysis != NULL)
+ rc = block->base->discipline->do_analysis(block);
+ if (rc) {
+ if (rc != -EAGAIN)
+ device->state = DASD_STATE_UNFMT;
+ return rc;
+ }
+ dasd_setup_queue(block);
+ set_capacity(block->gdp,
+ block->blocks << block->s2b_shift);
+ device->state = DASD_STATE_READY;
+ rc = dasd_scan_partitions(block);
+ if (rc)
+ device->state = DASD_STATE_BASIC;
+ } else {
+ device->state = DASD_STATE_READY;
+ }
return rc;
}
@@ -256,28 +296,31 @@ dasd_state_basic_to_ready(struct dasd_device * device)
* Forget format information. Check if the target level is basic
* and if it is create fake disk for formatting.
*/
-static int
-dasd_state_ready_to_basic(struct dasd_device * device)
+static int dasd_state_ready_to_basic(struct dasd_device *device)
{
int rc;
- rc = dasd_flush_ccw_queue(device, 0);
- if (rc)
- return rc;
- dasd_destroy_partitions(device);
- dasd_flush_request_queue(device);
- device->blocks = 0;
- device->bp_block = 0;
- device->s2b_shift = 0;
device->state = DASD_STATE_BASIC;
+ if (device->block) {
+ struct dasd_block *block = device->block;
+ rc = dasd_flush_block_queue(block);
+ if (rc) {
+ device->state = DASD_STATE_READY;
+ return rc;
+ }
+ dasd_destroy_partitions(block);
+ dasd_flush_request_queue(block);
+ block->blocks = 0;
+ block->bp_block = 0;
+ block->s2b_shift = 0;
+ }
return 0;
}
/*
* Back to basic.
*/
-static int
-dasd_state_unfmt_to_basic(struct dasd_device * device)
+static int dasd_state_unfmt_to_basic(struct dasd_device *device)
{
device->state = DASD_STATE_BASIC;
return 0;
@@ -291,17 +334,31 @@ dasd_state_unfmt_to_basic(struct dasd_device * device)
static int
dasd_state_ready_to_online(struct dasd_device * device)
{
+ int rc;
+
+ if (device->discipline->ready_to_online) {
+ rc = device->discipline->ready_to_online(device);
+ if (rc)
+ return rc;
+ }
device->state = DASD_STATE_ONLINE;
- dasd_schedule_bh(device);
+ if (device->block)
+ dasd_schedule_block_bh(device->block);
return 0;
}
/*
* Stop the requeueing of requests again.
*/
-static int
-dasd_state_online_to_ready(struct dasd_device * device)
+static int dasd_state_online_to_ready(struct dasd_device *device)
{
+ int rc;
+
+ if (device->discipline->online_to_ready) {
+ rc = device->discipline->online_to_ready(device);
+ if (rc)
+ return rc;
+ }
device->state = DASD_STATE_READY;
return 0;
}
@@ -309,8 +366,7 @@ dasd_state_online_to_ready(struct dasd_device * device)
/*
* Device startup state changes.
*/
-static int
-dasd_increase_state(struct dasd_device *device)
+static int dasd_increase_state(struct dasd_device *device)
{
int rc;
@@ -345,8 +401,7 @@ dasd_increase_state(struct dasd_device *device)
/*
* Device shutdown state changes.
*/
-static int
-dasd_decrease_state(struct dasd_device *device)
+static int dasd_decrease_state(struct dasd_device *device)
{
int rc;
@@ -381,8 +436,7 @@ dasd_decrease_state(struct dasd_device *device)
/*
* This is the main startup/shutdown routine.
*/
-static void
-dasd_change_state(struct dasd_device *device)
+static void dasd_change_state(struct dasd_device *device)
{
int rc;
@@ -409,17 +463,15 @@ dasd_change_state(struct dasd_device *device)
* dasd_kick_device will schedule a call do do_kick_device to the kernel
* event daemon.
*/
-static void
-do_kick_device(struct work_struct *work)
+static void do_kick_device(struct work_struct *work)
{
struct dasd_device *device = container_of(work, struct dasd_device, kick_work);
dasd_change_state(device);
- dasd_schedule_bh(device);
+ dasd_schedule_device_bh(device);
dasd_put_device(device);
}
-void
-dasd_kick_device(struct dasd_device *device)
+void dasd_kick_device(struct dasd_device *device)
{
dasd_get_device(device);
/* queue call to dasd_kick_device to the kernel event daemon. */
@@ -429,8 +481,7 @@ dasd_kick_device(struct dasd_device *device)
/*
* Set the target state for a device and starts the state change.
*/
-void
-dasd_set_target_state(struct dasd_device *device, int target)
+void dasd_set_target_state(struct dasd_device *device, int target)
{
/* If we are in probeonly mode stop at DASD_STATE_READY. */
if (dasd_probeonly && target > DASD_STATE_READY)
@@ -447,14 +498,12 @@ dasd_set_target_state(struct dasd_device *device, int target)
/*
* Enable devices with device numbers in [from..to].
*/
-static inline int
-_wait_for_device(struct dasd_device *device)
+static inline int _wait_for_device(struct dasd_device *device)
{
return (device->state == device->target);
}
-void
-dasd_enable_device(struct dasd_device *device)
+void dasd_enable_device(struct dasd_device *device)
{
dasd_set_target_state(device, DASD_STATE_ONLINE);
if (device->state <= DASD_STATE_KNOWN)
@@ -475,20 +524,20 @@ unsigned int dasd_profile_level = DASD_PROFILE_OFF;
/*
* Increments counter in global and local profiling structures.
*/
-#define dasd_profile_counter(value, counter, device) \
+#define dasd_profile_counter(value, counter, block) \
{ \
int index; \
for (index = 0; index < 31 && value >> (2+index); index++); \
dasd_global_profile.counter[index]++; \
- device->profile.counter[index]++; \
+ block->profile.counter[index]++; \
}
/*
* Add profiling information for cqr before execution.
*/
-static void
-dasd_profile_start(struct dasd_device *device, struct dasd_ccw_req * cqr,
- struct request *req)
+static void dasd_profile_start(struct dasd_block *block,
+ struct dasd_ccw_req *cqr,
+ struct request *req)
{
struct list_head *l;
unsigned int counter;
@@ -498,19 +547,19 @@ dasd_profile_start(struct dasd_device *device, struct dasd_ccw_req * cqr,
/* count the length of the chanq for statistics */
counter = 0;
- list_for_each(l, &device->ccw_queue)
+ list_for_each(l, &block->ccw_queue)
if (++counter >= 31)
break;
dasd_global_profile.dasd_io_nr_req[counter]++;
- device->profile.dasd_io_nr_req[counter]++;
+ block->profile.dasd_io_nr_req[counter]++;
}
/*
* Add profiling information for cqr after execution.
*/
-static void
-dasd_profile_end(struct dasd_device *device, struct dasd_ccw_req * cqr,
- struct request *req)
+static void dasd_profile_end(struct dasd_block *block,
+ struct dasd_ccw_req *cqr,
+ struct request *req)
{
long strtime, irqtime, endtime, tottime; /* in microseconds */
long tottimeps, sectors;
@@ -532,27 +581,27 @@ dasd_profile_end(struct dasd_device *device, struct dasd_ccw_req * cqr,
if (!dasd_global_profile.dasd_io_reqs)
memset(&dasd_global_profile, 0,
- sizeof (struct dasd_profile_info_t));
+ sizeof(struct dasd_profile_info_t));
dasd_global_profile.dasd_io_reqs++;
dasd_global_profile.dasd_io_sects += sectors;
- if (!device->profile.dasd_io_reqs)
- memset(&device->profile, 0,
- sizeof (struct dasd_profile_info_t));
- device->profile.dasd_io_reqs++;
- device->profile.dasd_io_sects += sectors;
+ if (!block->profile.dasd_io_reqs)
+ memset(&block->profile, 0,
+ sizeof(struct dasd_profile_info_t));
+ block->profile.dasd_io_reqs++;
+ block->profile.dasd_io_sects += sectors;
- dasd_profile_counter(sectors, dasd_io_secs, device);
- dasd_profile_counter(tottime, dasd_io_times, device);
- dasd_profile_counter(tottimeps, dasd_io_timps, device);
- dasd_profile_counter(strtime, dasd_io_time1, device);
- dasd_profile_counter(irqtime, dasd_io_time2, device);
- dasd_profile_counter(irqtime / sectors, dasd_io_time2ps, device);
- dasd_profile_counter(endtime, dasd_io_time3, device);
+ dasd_profile_counter(sectors, dasd_io_secs, block);
+ dasd_profile_counter(tottime, dasd_io_times, block);
+ dasd_profile_counter(tottimeps, dasd_io_timps, block);
+ dasd_profile_coun