Commit 19edabfd authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[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.
parent 8d21a7e3
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Bugreports.to..: <Linux390@de.ibm.com> * Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
* *
* $Revision: 1.136 $ * $Revision: 1.139 $
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -74,6 +74,8 @@ dasd_alloc_device(void) ...@@ -74,6 +74,8 @@ dasd_alloc_device(void)
if (device == NULL) if (device == NULL)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
memset(device, 0, sizeof (struct dasd_device)); 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. */ /* Get two pages for normal block device operations. */
device->ccw_mem = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, 1); 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, ...@@ -549,6 +551,7 @@ dasd_kmalloc_request(char *magic, int cplength, int datasize,
} }
strncpy((char *) &cqr->magic, magic, 4); strncpy((char *) &cqr->magic, magic, 4);
ASCEBC((char *) &cqr->magic, 4); ASCEBC((char *) &cqr->magic, 4);
set_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
dasd_get_device(device); dasd_get_device(device);
return cqr; return cqr;
} }
...@@ -597,6 +600,7 @@ dasd_smalloc_request(char *magic, int cplength, int datasize, ...@@ -597,6 +600,7 @@ dasd_smalloc_request(char *magic, int cplength, int datasize,
} }
strncpy((char *) &cqr->magic, magic, 4); strncpy((char *) &cqr->magic, magic, 4);
ASCEBC((char *) &cqr->magic, 4); ASCEBC((char *) &cqr->magic, 4);
set_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
dasd_get_device(device); dasd_get_device(device);
return cqr; return cqr;
} }
...@@ -688,9 +692,10 @@ dasd_term_IO(struct dasd_ccw_req * cqr) ...@@ -688,9 +692,10 @@ dasd_term_IO(struct dasd_ccw_req * cqr)
rc = ccw_device_clear(device->cdev, (long) cqr); rc = ccw_device_clear(device->cdev, (long) cqr);
switch (rc) { switch (rc) {
case 0: /* termination successful */ case 0: /* termination successful */
if (cqr->retries > 0) if (cqr->retries > 0) {
cqr->retries--;
cqr->status = DASD_CQR_QUEUED; cqr->status = DASD_CQR_QUEUED;
else } else
cqr->status = DASD_CQR_FAILED; cqr->status = DASD_CQR_FAILED;
cqr->stopclk = get_clock(); cqr->stopclk = get_clock();
break; break;
...@@ -982,6 +987,8 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, ...@@ -982,6 +987,8 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
irb->scsw.cstat == 0 && irb->scsw.cstat == 0 &&
!irb->esw.esw0.erw.cons) !irb->esw.esw0.erw.cons)
era = dasd_era_none; 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) else if (irb->esw.esw0.erw.cons)
era = device->discipline->examine_error(cqr, irb); era = device->discipline->examine_error(cqr, irb);
else else
...@@ -1875,7 +1882,7 @@ dasd_generic_set_offline (struct ccw_device *cdev) ...@@ -1875,7 +1882,7 @@ dasd_generic_set_offline (struct ccw_device *cdev)
* the blkdev_get in dasd_scan_partitions. We are only interested * the blkdev_get in dasd_scan_partitions. We are only interested
* in the other openers. * in the other openers.
*/ */
max_count = device->bdev ? 1 : 0; max_count = device->bdev ? 0 : -1;
if (atomic_read(&device->open_count) > max_count) { if (atomic_read(&device->open_count) > max_count) {
printk (KERN_WARNING "Can't offline dasd device with open" printk (KERN_WARNING "Can't offline dasd device with open"
" count = %i.\n", " count = %i.\n",
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Bugreports.to..: <Linux390@de.ibm.com> * Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001
* *
* $Revision: 1.28 $ * $Revision: 1.30 $
*/ */
#include <linux/timer.h> #include <linux/timer.h>
...@@ -1763,6 +1763,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense) ...@@ -1763,6 +1763,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
erp->magic = default_erp->magic; erp->magic = default_erp->magic;
erp->expires = 0; erp->expires = 0;
erp->retries = 256; erp->retries = 256;
cqr->buildclk = get_clock();
erp->status = DASD_CQR_FILLED; erp->status = DASD_CQR_FILLED;
/* remove the default erp */ /* remove the default erp */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Bugreports.to..: <Linux390@de.ibm.com> * Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
* *
* $Revision: 1.53 $ * $Revision: 1.54 $
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -1130,6 +1130,7 @@ dasd_eckd_release(struct block_device *bdev, int no, long args) ...@@ -1130,6 +1130,7 @@ dasd_eckd_release(struct block_device *bdev, int no, long args)
cqr->cpaddr->count = 32; cqr->cpaddr->count = 32;
cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
cqr->device = device; cqr->device = device;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
cqr->retries = 0; cqr->retries = 0;
cqr->expires = 2 * HZ; cqr->expires = 2 * HZ;
cqr->buildclk = get_clock(); cqr->buildclk = get_clock();
...@@ -1173,6 +1174,7 @@ dasd_eckd_reserve(struct block_device *bdev, int no, long args) ...@@ -1173,6 +1174,7 @@ dasd_eckd_reserve(struct block_device *bdev, int no, long args)
cqr->cpaddr->count = 32; cqr->cpaddr->count = 32;
cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
cqr->device = device; cqr->device = device;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
cqr->retries = 0; cqr->retries = 0;
cqr->expires = 2 * HZ; cqr->expires = 2 * HZ;
cqr->buildclk = get_clock(); cqr->buildclk = get_clock();
...@@ -1215,6 +1217,7 @@ dasd_eckd_steal_lock(struct block_device *bdev, int no, long args) ...@@ -1215,6 +1217,7 @@ dasd_eckd_steal_lock(struct block_device *bdev, int no, long args)
cqr->cpaddr->count = 32; cqr->cpaddr->count = 32;
cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
cqr->device = device; cqr->device = device;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
cqr->retries = 0; cqr->retries = 0;
cqr->expires = 2 * HZ; cqr->expires = 2 * HZ;
cqr->buildclk = get_clock(); cqr->buildclk = get_clock();
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Bugreports.to..: <Linux390@de.ibm.com> * Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
* *
* $Revision: 1.56 $ * $Revision: 1.57 $
*/ */
#ifndef DASD_INT_H #ifndef DASD_INT_H
...@@ -159,6 +159,7 @@ struct dasd_ccw_req { ...@@ -159,6 +159,7 @@ struct dasd_ccw_req {
struct ccw1 *cpaddr; /* address of channel program */ struct ccw1 *cpaddr; /* address of channel program */
char status; /* status of this request */ char status; /* status of this request */
short retries; /* A retry counter */ short retries; /* A retry counter */
unsigned long flags; /* flags of this request */
/* ... and how */ /* ... and how */
unsigned long starttime; /* jiffies time of request start */ unsigned long starttime; /* jiffies time of request start */
...@@ -192,6 +193,9 @@ struct dasd_ccw_req { ...@@ -192,6 +193,9 @@ struct dasd_ccw_req {
#define DASD_CQR_ERROR 0x04 /* request is completed with error */ #define DASD_CQR_ERROR 0x04 /* request is completed with error */
#define DASD_CQR_FAILED 0x05 /* request is finally failed */ #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. */ /* Signature for error recovery functions. */
typedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *); typedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *);
......
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