dasd_alias.c (eb6e199bef288611157b8198c25d12b32bf058d0) dasd_alias.c (f4ac1d0255748fe0f8e128a26b1c29490cae5c08)
1/*
2 * PAV alias management for the DASD ECKD discipline
3 *
4 * Copyright IBM Corporation, 2007
5 * Author(s): Stefan Weinhuber <wein@de.ibm.com>
6 */
7
8#define KMSG_COMPONENT "dasd-eckd"

--- 138 unchanged lines hidden (view full) ---

147 lcu->flags = NEED_UAC_UPDATE | UPDATE_PENDING;
148 INIT_LIST_HEAD(&lcu->lcu);
149 INIT_LIST_HEAD(&lcu->inactive_devices);
150 INIT_LIST_HEAD(&lcu->active_devices);
151 INIT_LIST_HEAD(&lcu->grouplist);
152 INIT_WORK(&lcu->suc_data.worker, summary_unit_check_handling_work);
153 INIT_DELAYED_WORK(&lcu->ruac_data.dwork, lcu_update_work);
154 spin_lock_init(&lcu->lock);
1/*
2 * PAV alias management for the DASD ECKD discipline
3 *
4 * Copyright IBM Corporation, 2007
5 * Author(s): Stefan Weinhuber <wein@de.ibm.com>
6 */
7
8#define KMSG_COMPONENT "dasd-eckd"

--- 138 unchanged lines hidden (view full) ---

147 lcu->flags = NEED_UAC_UPDATE | UPDATE_PENDING;
148 INIT_LIST_HEAD(&lcu->lcu);
149 INIT_LIST_HEAD(&lcu->inactive_devices);
150 INIT_LIST_HEAD(&lcu->active_devices);
151 INIT_LIST_HEAD(&lcu->grouplist);
152 INIT_WORK(&lcu->suc_data.worker, summary_unit_check_handling_work);
153 INIT_DELAYED_WORK(&lcu->ruac_data.dwork, lcu_update_work);
154 spin_lock_init(&lcu->lock);
155 init_completion(&lcu->lcu_setup);
155 return lcu;
156
157out_err4:
158 kfree(lcu->rsu_cqr->cpaddr);
159out_err3:
160 kfree(lcu->rsu_cqr);
161out_err2:
162 kfree(lcu->uac);

--- 72 unchanged lines hidden (view full) ---

235 private->lcu = lcu;
236 spin_unlock(&lcu->lock);
237 spin_unlock_irqrestore(&aliastree.lock, flags);
238
239 return is_lcu_known;
240}
241
242/*
156 return lcu;
157
158out_err4:
159 kfree(lcu->rsu_cqr->cpaddr);
160out_err3:
161 kfree(lcu->rsu_cqr);
162out_err2:
163 kfree(lcu->uac);

--- 72 unchanged lines hidden (view full) ---

236 private->lcu = lcu;
237 spin_unlock(&lcu->lock);
238 spin_unlock_irqrestore(&aliastree.lock, flags);
239
240 return is_lcu_known;
241}
242
243/*
244 * The first device to be registered on an LCU will have to do
245 * some additional setup steps to configure that LCU on the
246 * storage server. All further devices should wait with their
247 * initialization until the first device is done.
248 * To synchronize this work, the first device will call
249 * dasd_alias_lcu_setup_complete when it is done, and all
250 * other devices will wait for it with dasd_alias_wait_for_lcu_setup.
251 */
252void dasd_alias_lcu_setup_complete(struct dasd_device *device)
253{
254 struct dasd_eckd_private *private;
255 unsigned long flags;
256 struct alias_server *server;
257 struct alias_lcu *lcu;
258 struct dasd_uid *uid;
259
260 private = (struct dasd_eckd_private *) device->private;
261 uid = &private->uid;
262 lcu = NULL;
263 spin_lock_irqsave(&aliastree.lock, flags);
264 server = _find_server(uid);
265 if (server)
266 lcu = _find_lcu(server, uid);
267 spin_unlock_irqrestore(&aliastree.lock, flags);
268 if (!lcu) {
269 DBF_EVENT_DEVID(DBF_ERR, device->cdev,
270 "could not find lcu for %04x %02x",
271 uid->ssid, uid->real_unit_addr);
272 WARN_ON(1);
273 return;
274 }
275 complete_all(&lcu->lcu_setup);
276}
277
278void dasd_alias_wait_for_lcu_setup(struct dasd_device *device)
279{
280 struct dasd_eckd_private *private;
281 unsigned long flags;
282 struct alias_server *server;
283 struct alias_lcu *lcu;
284 struct dasd_uid *uid;
285
286 private = (struct dasd_eckd_private *) device->private;
287 uid = &private->uid;
288 lcu = NULL;
289 spin_lock_irqsave(&aliastree.lock, flags);
290 server = _find_server(uid);
291 if (server)
292 lcu = _find_lcu(server, uid);
293 spin_unlock_irqrestore(&aliastree.lock, flags);
294 if (!lcu) {
295 DBF_EVENT_DEVID(DBF_ERR, device->cdev,
296 "could not find lcu for %04x %02x",
297 uid->ssid, uid->real_unit_addr);
298 WARN_ON(1);
299 return;
300 }
301 wait_for_completion(&lcu->lcu_setup);
302}
303
304/*
243 * This function removes a device from the scope of alias management.
244 * The complicated part is to make sure that it is not in use by
245 * any of the workers. If necessary cancel the work.
246 */
247void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device)
248{
249 struct dasd_eckd_private *private;
250 unsigned long flags;

--- 661 unchanged lines hidden ---
305 * This function removes a device from the scope of alias management.
306 * The complicated part is to make sure that it is not in use by
307 * any of the workers. If necessary cancel the work.
308 */
309void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device)
310{
311 struct dasd_eckd_private *private;
312 unsigned long flags;

--- 661 unchanged lines hidden ---