From ccac47502d9ba128adf51eeb5876bda05db15655 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Sun, 23 Feb 2003 18:45:53 -0800 Subject: [PATCH] [PATCH] s390: dasd block device driver. updates for s390 dasd driver Some problems have been found in the dasd error handling code, they are fixed by the update to dasd_3990_erp.c. Dasd is one of only two remaining drivers that use the null elevator instead of iosched. Appearantly, the null elevator has some bitrot and can result in random data loss. For now, we just don't use it. --- drivers/s390/block/dasd.c | 5 +- drivers/s390/block/dasd_3990_erp.c | 76 +++++++++++++----------------- drivers/s390/block/dasd_eckd.c | 2 +- drivers/s390/block/dasd_ioctl.c | 6 +-- 4 files changed, 42 insertions(+), 47 deletions(-) diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 9c5a5c1adcb9e..925f885c47b6f 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -7,7 +7,7 @@ * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 * - * $Revision: 1.71 $ + * $Revision: 1.74 $ * * History of changes (starts July 2000) * 11/09/00 complete redesign after code review @@ -1656,17 +1656,20 @@ dasd_setup_blkdev(dasd_device_t * device) device->request_queue = kmalloc(sizeof (request_queue_t), GFP_KERNEL); if (device->request_queue == NULL) return -ENOMEM; + memset(device->request_queue, 0, sizeof(request_queue_t)); device->request_queue->queuedata = device; rc = blk_init_queue(device->request_queue, do_dasd_request, &device->request_queue_lock); if (rc) return rc; +#if 0 elevator_exit(device->request_queue); rc = elevator_init(device->request_queue, &elevator_noop); if (rc) { blk_cleanup_queue(device->request_queue); return rc; } +#endif blk_queue_hardsect_size(device->request_queue, device->bp_block); max = device->discipline->max_blocks << device->s2b_shift; blk_queue_max_sectors(device->request_queue, max); diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index 7539b8a1d8c87..59d584a40c865 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c @@ -5,7 +5,7 @@ * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001 * - * $Revision: 1.19 $ + * $Revision: 1.20 $ * * History of changes: * 05/14/01 fixed PL030160GTO (BUG() in erp_action_5) @@ -454,7 +454,7 @@ dasd_3990_erp_action_4(dasd_ccw_req_t * erp, char *sense) } else { - if (sense[25] & 0x1D) { /* state change pending */ + if (sense[25] == 0x1D) { /* state change pending */ DEV_MESSAGE(KERN_INFO, device, "%s", "waiting for state change pending " "int"); @@ -464,6 +464,10 @@ dasd_3990_erp_action_4(dasd_ccw_req_t * erp, char *sense) } else { /* no state change pending - retry */ + DEV_MESSAGE (KERN_INFO, device, + "redriving request immediately, " + "%d retries left", + erp->retries); erp->status = DASD_CQR_QUEUED; } } @@ -2273,27 +2277,41 @@ dasd_3990_erp_add_erp(dasd_ccw_req_t * cqr) { dasd_device_t *device = cqr->device; + struct ccw1 *ccw; /* allocate additional request block */ dasd_ccw_req_t *erp; - erp = dasd_alloc_erp_request((char *) &cqr->magic, 1, 0, cqr->device); + erp = dasd_alloc_erp_request((char *) &cqr->magic, 2, 0, cqr->device); if (IS_ERR(erp)) { - DEV_MESSAGE(KERN_ERR, device, "%s", - "Unable to allocate ERP request"); - cqr->status = DASD_CQR_FAILED; + if (cqr->retries <= 0) { + DEV_MESSAGE(KERN_ERR, device, "%s", + "Unable to allocate ERP request"); + cqr->status = DASD_CQR_FAILED; + cqr->stopclk = get_clock (); + } else { + DEV_MESSAGE (KERN_ERR, device, + "Unable to allocate ERP request " + "(%i retries left)", + cqr->retries); + dasd_set_timer(device, (HZ << 3)); + } return cqr; } /* initialize request with default TIC to current ERP/CQR */ - erp->cpaddr->cmd_code = CCW_CMD_TIC; - erp->cpaddr->cda = (long) (cqr->cpaddr); + ccw = erp->cpaddr; + ccw->cmd_code = CCW_CMD_NOOP; + ccw->flags = CCW_FLAG_CC; + ccw++; + ccw->cmd_code = CCW_CMD_TIC; + ccw->cda = (long)(cqr->cpaddr); erp->function = dasd_3990_erp_add_erp; - erp->refers = cqr; - erp->device = cqr->device; - erp->magic = cqr->magic; - erp->expires = 0; - erp->retries = 256; + erp->refers = cqr; + erp->device = cqr->device; + erp->magic = cqr->magic; + erp->expires = 0; + erp->retries = 256; erp->status = DASD_CQR_FILLED; @@ -2362,7 +2380,7 @@ dasd_3990_erp_error_match(dasd_ccw_req_t * cqr1, dasd_ccw_req_t * cqr2) } /* check sense data; byte 0-2,25,27 */ - if (!((strncmp(cqr1->dstat->ecw, cqr2->dstat->ecw, 3) == 0) && + if (!((memcmp (cqr1->dstat->ecw, cqr2->dstat->ecw, 3) == 0) && (cqr1->dstat->ecw[27] == cqr2->dstat->ecw[27]) && (cqr1->dstat->ecw[25] == cqr2->dstat->ecw[25]))) { @@ -2549,7 +2567,7 @@ dasd_3990_erp_handle_match_erp(dasd_ccw_req_t * erp_head, dasd_ccw_req_t * erp) if (erp->retries > 0) { - char *sense = erp->dstat->ecw; + char *sense = erp->refers->dstat->ecw; /* check for special retries */ if (erp->function == dasd_3990_erp_action_4) { @@ -2680,35 +2698,9 @@ dasd_3990_erp_action(dasd_ccw_req_t * cqr) dasd_log_ccw(erp, 1, cpa); /* enqueue added ERP request */ - if ((erp != cqr) && (erp->status == DASD_CQR_FILLED)) { + if (erp->status == DASD_CQR_FILLED) { erp->status = DASD_CQR_QUEUED; list_add(&erp->list, &device->ccw_queue); - } else { - if ((erp->status == DASD_CQR_FILLED) || (erp != cqr)) { - /* something strange happened - log the error and throw a BUG() */ - DEV_MESSAGE(KERN_ERR, device, "%s", - "Problems with ERP chain!!! BUG"); - - /* print current erp_chain */ - DEV_MESSAGE(KERN_DEBUG, device, "%s", - "ERP chain at END of ERP-ACTION"); - { - dasd_ccw_req_t *temp_erp = NULL; - for (temp_erp = erp; - temp_erp != NULL; - temp_erp = temp_erp->refers) { - - DEV_MESSAGE(KERN_DEBUG, device, - " erp %p (function %p)" - " refers to %p", - temp_erp, - temp_erp->function, - temp_erp->refers); - } - } - BUG(); - } - } return erp; diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index fb51d7fb37919..55ce8a8a092fc 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -7,7 +7,7 @@ * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * - * $Revision: 1.35 $ + * $Revision: 1.36 $ * * History of changes (starts July 2000) * 07/11/00 Enabled rotational position sensing diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index e570db2497bd6..3b84084989fc5 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c @@ -111,7 +111,7 @@ dasd_ioctl(struct inode *inp, struct file *filp, ioctl = list_entry(l, dasd_ioctl_list_t, list); if (ioctl->no == no) { /* Found a matching ioctl. Call it. */ - if (try_module_get(ioctl->owner) != 0) + if (!try_module_get(ioctl->owner)) continue; rc = ioctl->handler(bdev, no, data); module_put(ioctl->owner); @@ -263,7 +263,7 @@ dasd_ioctl_reset_profile(struct block_device *bdev, int no, long args) if (!capable(CAP_SYS_ADMIN)) return -EACCES; - device = = bdev->bd_disk->private_data; + device = bdev->bd_disk->private_data; if (device == NULL) return -ENODEV; @@ -279,7 +279,7 @@ dasd_ioctl_read_profile(struct block_device *bdev, int no, long args) { dasd_device_t *device; - device = = bdev->bd_disk->private_data; + device = bdev->bd_disk->private_data; if (device == NULL) return -ENODEV; -- 2.53.0