|
@@ -264,8 +264,10 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device)
|
|
spin_unlock_irqrestore(&lcu->lock, flags);
|
|
spin_unlock_irqrestore(&lcu->lock, flags);
|
|
cancel_work_sync(&lcu->suc_data.worker);
|
|
cancel_work_sync(&lcu->suc_data.worker);
|
|
spin_lock_irqsave(&lcu->lock, flags);
|
|
spin_lock_irqsave(&lcu->lock, flags);
|
|
- if (device == lcu->suc_data.device)
|
|
|
|
|
|
+ if (device == lcu->suc_data.device) {
|
|
|
|
+ dasd_put_device(device);
|
|
lcu->suc_data.device = NULL;
|
|
lcu->suc_data.device = NULL;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
was_pending = 0;
|
|
was_pending = 0;
|
|
if (device == lcu->ruac_data.device) {
|
|
if (device == lcu->ruac_data.device) {
|
|
@@ -273,8 +275,10 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device)
|
|
was_pending = 1;
|
|
was_pending = 1;
|
|
cancel_delayed_work_sync(&lcu->ruac_data.dwork);
|
|
cancel_delayed_work_sync(&lcu->ruac_data.dwork);
|
|
spin_lock_irqsave(&lcu->lock, flags);
|
|
spin_lock_irqsave(&lcu->lock, flags);
|
|
- if (device == lcu->ruac_data.device)
|
|
|
|
|
|
+ if (device == lcu->ruac_data.device) {
|
|
|
|
+ dasd_put_device(device);
|
|
lcu->ruac_data.device = NULL;
|
|
lcu->ruac_data.device = NULL;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
private->lcu = NULL;
|
|
private->lcu = NULL;
|
|
spin_unlock_irqrestore(&lcu->lock, flags);
|
|
spin_unlock_irqrestore(&lcu->lock, flags);
|
|
@@ -549,8 +553,10 @@ static void lcu_update_work(struct work_struct *work)
|
|
if ((rc && (rc != -EOPNOTSUPP)) || (lcu->flags & NEED_UAC_UPDATE)) {
|
|
if ((rc && (rc != -EOPNOTSUPP)) || (lcu->flags & NEED_UAC_UPDATE)) {
|
|
DBF_DEV_EVENT(DBF_WARNING, device, "could not update"
|
|
DBF_DEV_EVENT(DBF_WARNING, device, "could not update"
|
|
" alias data in lcu (rc = %d), retry later", rc);
|
|
" alias data in lcu (rc = %d), retry later", rc);
|
|
- schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ);
|
|
|
|
|
|
+ if (!schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ))
|
|
|
|
+ dasd_put_device(device);
|
|
} else {
|
|
} else {
|
|
|
|
+ dasd_put_device(device);
|
|
lcu->ruac_data.device = NULL;
|
|
lcu->ruac_data.device = NULL;
|
|
lcu->flags &= ~UPDATE_PENDING;
|
|
lcu->flags &= ~UPDATE_PENDING;
|
|
}
|
|
}
|
|
@@ -593,8 +599,10 @@ static int _schedule_lcu_update(struct alias_lcu *lcu,
|
|
*/
|
|
*/
|
|
if (!usedev)
|
|
if (!usedev)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
+ dasd_get_device(usedev);
|
|
lcu->ruac_data.device = usedev;
|
|
lcu->ruac_data.device = usedev;
|
|
- schedule_delayed_work(&lcu->ruac_data.dwork, 0);
|
|
|
|
|
|
+ if (!schedule_delayed_work(&lcu->ruac_data.dwork, 0))
|
|
|
|
+ dasd_put_device(usedev);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -723,7 +731,7 @@ static int reset_summary_unit_check(struct alias_lcu *lcu,
|
|
ASCEBC((char *) &cqr->magic, 4);
|
|
ASCEBC((char *) &cqr->magic, 4);
|
|
ccw = cqr->cpaddr;
|
|
ccw = cqr->cpaddr;
|
|
ccw->cmd_code = DASD_ECKD_CCW_RSCK;
|
|
ccw->cmd_code = DASD_ECKD_CCW_RSCK;
|
|
- ccw->flags = 0 ;
|
|
|
|
|
|
+ ccw->flags = CCW_FLAG_SLI;
|
|
ccw->count = 16;
|
|
ccw->count = 16;
|
|
ccw->cda = (__u32)(addr_t) cqr->data;
|
|
ccw->cda = (__u32)(addr_t) cqr->data;
|
|
((char *)cqr->data)[0] = reason;
|
|
((char *)cqr->data)[0] = reason;
|
|
@@ -930,6 +938,7 @@ static void summary_unit_check_handling_work(struct work_struct *work)
|
|
/* 3. read new alias configuration */
|
|
/* 3. read new alias configuration */
|
|
_schedule_lcu_update(lcu, device);
|
|
_schedule_lcu_update(lcu, device);
|
|
lcu->suc_data.device = NULL;
|
|
lcu->suc_data.device = NULL;
|
|
|
|
+ dasd_put_device(device);
|
|
spin_unlock_irqrestore(&lcu->lock, flags);
|
|
spin_unlock_irqrestore(&lcu->lock, flags);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -989,6 +998,8 @@ void dasd_alias_handle_summary_unit_check(struct dasd_device *device,
|
|
}
|
|
}
|
|
lcu->suc_data.reason = reason;
|
|
lcu->suc_data.reason = reason;
|
|
lcu->suc_data.device = device;
|
|
lcu->suc_data.device = device;
|
|
|
|
+ dasd_get_device(device);
|
|
spin_unlock(&lcu->lock);
|
|
spin_unlock(&lcu->lock);
|
|
- schedule_work(&lcu->suc_data.worker);
|
|
|
|
|
|
+ if (!schedule_work(&lcu->suc_data.worker))
|
|
|
|
+ dasd_put_device(device);
|
|
};
|
|
};
|