diff options
| author | Andrew Morton <akpm@osdl.org> | 2004-04-21 23:35:26 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-04-21 23:35:26 -0700 |
| commit | 19edabfd60ba30c49c15a122cc90b87d96bcff91 (patch) | |
| tree | a2cd40c201285766d3b7b5236c7c9ea809f279bc | |
| parent | 8d21a7e30685ac7632c4fdc199d08ac7325ed9ca (diff) | |
[PATCH] s390: dasd device driver.
From: Martin Schwidefsky <schwidefsky@de.ibm.com>
dasd device driver changes:
- Initialize open_count with -1 to account for blkdev_open in
dasd_scan_partitions.
- Introduce USE_ERP request flag to selectivly switch off error
recovery for reserve, release & unconditional reserve ioctls.
| -rw-r--r-- | drivers/s390/block/dasd.c | 15 | ||||
| -rw-r--r-- | drivers/s390/block/dasd_3990_erp.c | 3 | ||||
| -rw-r--r-- | drivers/s390/block/dasd_eckd.c | 5 | ||||
| -rw-r--r-- | drivers/s390/block/dasd_int.h | 6 |
4 files changed, 22 insertions, 7 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index d0ab034fa0c1..ab9f28443436 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -7,7 +7,7 @@ * Bugreports.to..: <Linux390@de.ibm.com> * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 * - * $Revision: 1.136 $ + * $Revision: 1.139 $ */ #include <linux/config.h> @@ -74,6 +74,8 @@ dasd_alloc_device(void) if (device == NULL) return ERR_PTR(-ENOMEM); memset(device, 0, sizeof (struct dasd_device)); + /* 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); @@ -549,6 +551,7 @@ dasd_kmalloc_request(char *magic, int cplength, int datasize, } strncpy((char *) &cqr->magic, magic, 4); ASCEBC((char *) &cqr->magic, 4); + set_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); dasd_get_device(device); return cqr; } @@ -597,6 +600,7 @@ dasd_smalloc_request(char *magic, int cplength, int datasize, } strncpy((char *) &cqr->magic, magic, 4); ASCEBC((char *) &cqr->magic, 4); + set_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); dasd_get_device(device); return cqr; } @@ -688,9 +692,10 @@ dasd_term_IO(struct dasd_ccw_req * cqr) rc = ccw_device_clear(device->cdev, (long) cqr); switch (rc) { case 0: /* termination successful */ - if (cqr->retries > 0) + if (cqr->retries > 0) { + cqr->retries--; cqr->status = DASD_CQR_QUEUED; - else + } else cqr->status = DASD_CQR_FAILED; cqr->stopclk = get_clock(); break; @@ -982,6 +987,8 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, irb->scsw.cstat == 0 && !irb->esw.esw0.erw.cons) era = dasd_era_none; + else if (!test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags)) + era = dasd_era_fatal; /* don't recover this request */ else if (irb->esw.esw0.erw.cons) era = device->discipline->examine_error(cqr, irb); else @@ -1875,7 +1882,7 @@ dasd_generic_set_offline (struct ccw_device *cdev) * the blkdev_get in dasd_scan_partitions. We are only interested * in the other openers. */ - max_count = device->bdev ? 1 : 0; + max_count = device->bdev ? 0 : -1; if (atomic_read(&device->open_count) > max_count) { printk (KERN_WARNING "Can't offline dasd device with open" " count = %i.\n", diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index c6b26e729aaa..e90c1c93e19a 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c @@ -5,7 +5,7 @@ * Bugreports.to..: <Linux390@de.ibm.com> * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001 * - * $Revision: 1.28 $ + * $Revision: 1.30 $ */ #include <linux/timer.h> @@ -1763,6 +1763,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense) erp->magic = default_erp->magic; erp->expires = 0; erp->retries = 256; + cqr->buildclk = get_clock(); erp->status = DASD_CQR_FILLED; /* remove the default erp */ diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 1490f1e4a4ec..e7afb426b539 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -7,7 +7,7 @@ * Bugreports.to..: <Linux390@de.ibm.com> * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * - * $Revision: 1.53 $ + * $Revision: 1.54 $ */ #include <linux/config.h> @@ -1130,6 +1130,7 @@ dasd_eckd_release(struct block_device *bdev, int no, long args) cqr->cpaddr->count = 32; cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; cqr->device = device; + clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); cqr->retries = 0; cqr->expires = 2 * HZ; cqr->buildclk = get_clock(); @@ -1173,6 +1174,7 @@ dasd_eckd_reserve(struct block_device *bdev, int no, long args) cqr->cpaddr->count = 32; cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; cqr->device = device; + clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); cqr->retries = 0; cqr->expires = 2 * HZ; cqr->buildclk = get_clock(); @@ -1215,6 +1217,7 @@ dasd_eckd_steal_lock(struct block_device *bdev, int no, long args) cqr->cpaddr->count = 32; cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; cqr->device = device; + clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); cqr->retries = 0; cqr->expires = 2 * HZ; cqr->buildclk = get_clock(); diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 70ccb1110d07..9967c082c0ad 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h @@ -6,7 +6,7 @@ * Bugreports.to..: <Linux390@de.ibm.com> * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * - * $Revision: 1.56 $ + * $Revision: 1.57 $ */ #ifndef DASD_INT_H @@ -159,6 +159,7 @@ struct dasd_ccw_req { struct ccw1 *cpaddr; /* address of channel program */ char status; /* status of this request */ short retries; /* A retry counter */ + unsigned long flags; /* flags of this request */ /* ... and how */ unsigned long starttime; /* jiffies time of request start */ @@ -192,6 +193,9 @@ struct dasd_ccw_req { #define DASD_CQR_ERROR 0x04 /* request is completed with error */ #define DASD_CQR_FAILED 0x05 /* request is finally failed */ +/* per dasd_ccw_req flags */ +#define DASD_CQR_FLAGS_USE_ERP 0 /* use ERP for this request */ + /* Signature for error recovery functions. */ typedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *); |
